Побочный эффект (информатика)
В информатике , что операция, функция или выражение говорят имеют побочный эффект , если они имеют какой-либо наблюдаемый эффект, отличный от основного эффекта считывания значения аргументов и возврата значения инициатору операции. Примеры побочных эффектов включают изменение или чтение нелокальной переменной , статической локальной переменной или изменяемого аргумента, передаваемого по ссылке ; возникновение ошибок или исключений; выполнение ввода-вывода ; или вызов других функций с побочными эффектами. [1] При наличии побочных эффектов поведение программы может зависеть от истории; то есть порядок оценки имеет значение. Понимание и отладка функции с побочными эффектами требует знаний о контексте и ее возможной истории. [2] [3] Побочные эффекты играют важную роль при разработке и анализе языков программирования . Степень использования побочных эффектов зависит от парадигмы программирования. Например, императивное программирование обычно используется для создания побочных эффектов, для обновления состояния системы. Напротив, декларативное программирование обычно используется для сообщения о состоянии системы без побочных эффектов.
Функциональное программирование направлено на минимизацию или устранение побочных эффектов. Отсутствие побочных эффектов облегчает формальную проверку программы. Функциональный язык Haskell устраняет побочные эффекты, такие как ввод-вывод и другие вычисления с сохранением состояния, заменяя их монадическими действиями. [4] [5] Функциональные языки, такие как Standard ML , Scheme и Scala, не ограничивают побочные эффекты, но программисты обычно их избегают. [6]
Программисты на языке ассемблера должны знать о скрытых побочных эффектах — инструкциях, которые изменяют части состояния процессора, не упомянутые в мнемонике инструкции. Классическим примером скрытого побочного эффекта является арифметическая инструкция, которая неявно изменяет коды условий (скрытый побочный эффект), одновременно изменяя регистр (предполагаемый эффект). Одним из потенциальных недостатков набора команд со скрытыми побочными эффектами является то, что если многие инструкции имеют побочные эффекты на одну часть состояния, например коды условий, то логика, необходимая для последовательного обновления этого состояния, может стать узким местом производительности. Проблема особенно остра на некоторых процессорах, разработанных с конвейерной обработкой (с 1990 года) или с внеочередным выполнением . Такому процессору может потребоваться дополнительная схема управления для обнаружения скрытых побочных эффектов и остановки конвейера, если следующая инструкция зависит от результатов этих эффектов.
Ссылочная прозрачность [ править ]
Отсутствие побочных эффектов является необходимым, но недостаточным условием ссылочной прозрачности. Ссылочная прозрачность означает, что выражение (например, вызов функции) можно заменить его значением. Для этого требуется, чтобы выражение было чистым , то есть выражение должно быть детерминированным (всегда давать одно и то же значение для одних и тех же входных данных) и не иметь побочных эффектов.
побочные Временные эффекты
Побочные эффекты, вызванные временем, затрачиваемым на выполнение операции, обычно игнорируются при обсуждении побочных эффектов и ссылочной прозрачности. В некоторых случаях, например при аппаратном синхронизации или тестировании, операции вставляются специально из-за их временных побочных эффектов, например sleep(5000)
или for (int i = 0; i < 10000; ++i) {}
. Эти инструкции не меняют состояние, за исключением того, что их выполнение занимает некоторое время.
Идемпотентность [ править ]
Подпрограмма математическом с побочными эффектами является идемпотентной, если несколько применений подпрограммы оказывают такое же влияние на состояние системы, как и одно приложение, другими словами, если функция из пространства состояний системы в себя, связанная с подпрограммой, идемпотентна в смысле . Например, рассмотрим следующую программу Python :
x = 0
def setx(n):
global x
x = n
setx(3)
assert x == 3
setx(3)
assert x == 3
setx
является идемпотентным, поскольку второе применение setx
до 3 оказывает такое же влияние на состояние системы, как и первое приложение: x
уже было установлено значение 3 после первого применения и по-прежнему установлено на 3 после второго применения.
идемпотентна Чистая функция , если она идемпотентна в математическом смысле . Например, рассмотрим следующую программу Python:
def abs(n):
return -n if n < 0 else n
assert abs(abs(-3)) == abs(-3)
abs
является идемпотентным, поскольку второе применение abs
к возвращаемому значению первого приложения до -3 возвращает то же значение, что и первое приложение до -3.
Пример [ править ]
из распространенных демонстраций поведения побочных эффектов является оператор присваивания в C. Одной Задание a = b
это выражение, которое имеет то же значение, что и выражение b
, с побочным эффектом сохранения R- значения b
в L- значение a
. Это позволяет множественное назначение:
a = (b = 3); // b = 3 evaluates to 3, which then gets assigned to a
Поскольку право оператора связывает , это эквивалентно
a = b = 3;
Это представляет собой потенциальное зависание для начинающих программистов, которые могут запутать
while (b == 3) {} // tests if b evaluates to 3
с
while (b = 3) {} // b = 3 evaluates to 3, which then casts to true so the loop is infinite
См. также [ править ]
- Действие на расстоянии (компьютерное программирование)
- Неважный термин
- Точка последовательности
- Атака по побочному каналу
- Неопределенное поведение
- Неопределенное поведение
Ссылки [ править ]
- ^ Спулер, Дэвид А.; Саджив, А. Сайед Мухаммед (январь 1994 г.). Обнаружение компилятором побочных эффектов вызова функций . Университет Джеймса Кука . CiteSeerX 10.1.1.70.2096 .
Термин «побочный эффект» относится к модификации нелокальной среды. Обычно это происходит, когда функция (или процедура) изменяет глобальную переменную или аргументы, передаваемые ссылочными параметрами. Но есть и другие способы изменения нелокальной среды. Мы рассматриваем следующие причины побочных эффектов при вызове функции: 1. Выполнение ввода-вывода. 2. Изменение глобальных переменных. 3. Изменение локальных постоянных переменных (например, статических переменных в C). 4. Изменение аргумента, передаваемого по ссылке. 5. Изменение локальной переменной, автоматической или статической, функции, расположенной выше в последовательности вызова функции (обычно с помощью указателя).
- ^ Тернер, Дэвид А. , изд. (1990). Темы исследований по функциональному программированию . Аддисон-Уэсли . стр. 17–42. С помощью Хьюз, Джон. «Почему функциональное программирование имеет значение» (PDF) . Архивировано (PDF) из оригинала 14 июня 2022 г. Проверено 6 августа 2022 г.
- ^ Коллберг, Кристиан С. (22 апреля 2005 г.). «CSc 520 Основы языков программирования» . Департамент компьютерных наук Университета Аризоны . Архивировано из оригинала 06 августа 2022 г. Проверено 6 августа 2022 г.
- ^ «Отчет Haskell 98» . 1998.
- ^ Джонс, Саймон Пейтон; Уодлер, Фил (1993). Императивное функциональное программирование . Протокол конференции 20-го ежегодного симпозиума ACM по принципам языков программирования. стр. 71–84.
- ^ Феллизен, Матиас ; Финдлер, Роберт Брюс; Флэтт, Мэтью; Кришнамурти, Шрирам (01 августа 2014 г.). «Как разрабатывать программы» (2-е изд.). МТИ Пресс .