Побічний ефект (програмування)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Кажуть, що функція або вираз мають побічний ефект, якщо, на додаток до повернення значення, вони змінюють якийсь стан програми або провадять видиму взаємодію з викликальною функцією або зовнішнім світом. Наприклад функція може змніювати глобальну або статичну змінну, змінювати один зі своїх аргументів, спричиняти виняткову ситуацію, виводити дані на пристрій виведення або файл, читати дані або викликати інші функції з побічними ефектами. За наявності побічних ефектів, поведінка програми залежить від історії; тобто порядок обчислень має значення. Розуміння програми з побічними ефектами вимагає знаття про контекст та історію; навіть при наявності цих знань важко добрати перебіг програми, а також зневадити її.[1][2]

Побічні ефекти найзвичніший спосіб взаємодії з зовнішнім світом (людьми, файловою системою, іншими комп'ютерами в мережі). Ступінь використання побічних ефектів залежить від парадигми програмування. Імперативне програмування відоме частим використанням побічних ефектів. У функціональному програмуванні побічні ефекти використовують зрідка. Функціональні мови такі як Standard ML або Scheme не забороняють побічні ефекти, але зазвичай програмісти уникають їх.[3] Функціональна мова Haskell обмежує побічні ефекти через статичну систему типізації; вона використовує концепцію монад.[4][5]

Розробники на мові асемблера мають зважати на приховані побічні ефекти — інструкції, які змінюють частину стану процесора без зазначення цього в своїх назвах. Класичний приклад прихованого побічного ефекту це арифметична інструкція, яка явно змінює регістр (явний ефект (англ. overt effect)) і неявно змінює коди умов (прихований побічний ефект), приміром, прапорці, що вказують на те, що в результаті отримано нуль або переповнення. Один з недоліків набору інструкцій з багатьма побічними ефектами полягає в можливості впливу на одну частинку стану, наприклад коди умов, тоді коли вимога оновлювати ці стани послідовно може стати вузьким місцем швидкодії. Проблема постає особливо гостро на процесорах розроблених з конвеєром команд (з 1990) або з позачерговим виконанням. Такі процесори можуть потребувати додаткову схему для переврки на побічні ефекти і зупиняти конвеєр, якщо наступна інструкція залежить від наслідків цих ефектів.

Прозорість посилань[ред.ред. код]

Відсутність побічних ефектів є необхідною, але не достатньою умовою для прозорості посилань. Прозорість посилань значить, що вираз (такий як виклик функції) може бути заміненим на його значення; для цього необхідно, щоб вираз не тільки не мав побічних ефектів, але й був чистим (завжди повертав той самий результат для одних вхідних даних).

Часові побічні ефекти[ред.ред. код]

На побічні ефекти пов'язані з часом необхідним для виконання дії, зазвичай не зважають, коли йдеться про побічні ефекти або прозорість посилань. В більшості програм бажано заміняти довгі дії на коротші, наприклад, (60 / 3 * 2) на 40. Іноді, коли йдеться про синхронізацію або тестування, зумисне вставляються такі коди, що мають часовий побічний ефект, наприклад, Sleep(5000) або for(i=0; i < 10000; i++){}. Ці інструкції не змінюють стан окрім потреби очікування до їх завершення.

Ідемпотентність[ред.ред. код]

Функція без побічних ефектів f завжди ідемпотентна (в розумінні послідовних викликів f ; f, але не композиції функцій ff).

Примітки[ред.ред. код]

  1. “Research Topics in Functional Programming” ed. D. Turner, Addison-Wesley, 1990, pp 17–42. Retrieved from: Hughes, John (PDF), Why Functional Programming Matters, http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf 
  2. Collberg, CSc 520 Principles of Programming Languages, Department of Computer Science, University of Arizona, http://www.cs.arizona.edu/~collberg/Teaching/520/2005/Html/Html-24/index.html 
  3. Matthias Felleisen et al., How To Design Programs, MIT Press
  4. Haskell 98 report, http://www.haskell.org.
  5. Imperative Functional Programming, Simon Peyton Jones and Phil Wadler, Conference Record of the 20th Annual ACM Symposium on Principles of Programming Languages, pages 71–84, 1993