Побочный эффект (информатика) - Side effect (computer science)

В информатике считается , что операция, функция или выражение имеют побочный эффект, если они изменяют некоторые значения переменных состояния вне своей локальной среды, то есть имеют наблюдаемый эффект помимо возврата значения (предполагаемого эффекта) в инициатор операции. Данные состояния, обновленные «вне» операции, могут поддерживаться «внутри» объекта с отслеживанием состояния или более широкой системы с отслеживанием состояния, в которой выполняется операция. Примеры побочных эффектов включают изменение нелокальной переменной , изменение статической локальной переменной , изменение изменяемого аргумента, переданного по ссылке , выполнение ввода-вывода или вызов других функций побочного эффекта. При наличии побочных эффектов поведение программы может зависеть от истории; то есть порядок оценки имеет значение. Понимание и отладка функции с побочными эффектами требует знания контекста и его возможных историй.

Степень использования побочных эффектов зависит от парадигмы программирования. Императивное программирование обычно используется для создания побочных эффектов, чтобы обновить состояние системы. Напротив, декларативное программирование обычно используется для сообщения о состоянии системы без побочных эффектов.

В функциональном программировании побочные эффекты используются редко. Отсутствие побочных эффектов упрощает формальную проверку программы. Функциональные языки, такие как Standard ML , Scheme и Scala , не ограничивают побочные эффекты, но программисты обычно их избегают. Функциональный язык Haskell выражает побочные эффекты, такие как ввод-вывод и другие вычисления с сохранением состояния, с помощью монадических действий.

Программисты на языке ассемблера должны знать о скрытых побочных эффектах - инструкциях, которые изменяют части состояния процессора, которые не упоминаются в мнемонике инструкции. Классическим примером скрытого побочного эффекта является арифметическая инструкция, которая неявно изменяет коды условий (скрытый побочный эффект), в то время как она явно изменяет регистр (предполагаемый эффект). Одним из потенциальных недостатков набора инструкций со скрытыми побочными эффектами является то, что, если многие инструкции имеют побочные эффекты на одну часть состояния, например коды условий, то логика, необходимая для последовательного обновления этого состояния, может стать узким местом производительности. Проблема особенно остро стоит на некоторых процессорах, разработанных с конвейерной обработкой (с 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является идемпотентным, потому что второе применение значения setx3 оказывает такое же влияние на состояние системы, как и первое приложение: оно 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

Смотрите также

использованная литература

  1. ^ Спулер, Дэвид А .; Саджиев, ASM (январь 1994 г.). «Обнаружение компилятором побочных эффектов вызова функции». Университет Джеймса Кука. CiteSeerX  10.1.1.70.2096 . Термин «побочный эффект» относится к модификации нелокальной среды. Обычно это происходит, когда функция (или процедура) изменяет глобальную переменную или аргументы, переданные с помощью ссылочных параметров. Но есть и другие способы изменения нелокальной среды. Мы рассматриваем следующие причины побочных эффектов при вызове функции: 1. Выполнение ввода-вывода. 2. Изменение глобальных переменных. 3. Изменение локальных постоянных переменных (например, статических переменных в C). 4. Изменение аргумента, переданного по ссылке. 5. Изменение локальной переменной, автоматическое или статическое, функции выше в последовательности вызова функции (обычно с помощью указателя). Цитировать журнал требует |journal=( помощь )
  2. ^ «Темы исследований в функциональном программировании» под ред. Д. Тернер, Эддисон-Уэсли, 1990, стр. 17–42. Получено из: Хьюз, Джон, Почему функциональное программирование имеет значение (PDF)
  3. ^ Коллберг, CSc 520 Принципы языков программирования , Департамент компьютерных наук, Университет Аризоны
  4. ^ Маттиас Фелляйзен и др., Как разрабатывать программы , MIT Press
  5. ^ Отчет Haskell 98, http://www.haskell.org .
  6. ^ Императивное функциональное программирование , Саймон Пейтон Джонс и Фил Уодлер, Отчет о конференции 20-го ежегодного симпозиума ACM по принципам языков программирования , страницы 71–84, 1993