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

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

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

В функциональное программирование, побочные эффекты используются редко. Отсутствие побочных эффектов облегчает выполнение формальные проверки программы. Функциональные языки, такие как Стандартный ML, Схема и Scala не ограничивают побочные эффекты, но программисты обычно их избегают.[4] Функциональный язык Haskell выражает побочные эффекты, такие как Ввод / вывод и другие вычисления с сохранением состояния с использованием монадический действия.[5][6]

язык ассемблера программисты должны знать скрытый побочные эффекты - инструкции, которые изменяют части состояния процессора, не упомянутые в мнемонике инструкции. Классическим примером скрытого побочного эффекта является арифметическая инструкция, которая неявно изменяет коды состояния (скрытый побочный эффект), в то время как он явно изменяет регистр (явный эффект). Один потенциальный недостаток Набор инструкций со скрытыми побочными эффектами заключается в том, что, если многие инструкции имеют побочные эффекты на одну часть состояния, например коды условий, то логика, необходимая для последовательного обновления этого состояния, может стать узким местом производительности. Проблема особенно остро стоит на некоторых процессорах, разработанных с конвейерная обработка (с 1990 г.) или с внеочередное исполнение. Такому процессору может потребоваться дополнительная схема управления для обнаружения скрытых побочных эффектов и остановки конвейера, если следующая инструкция зависит от результатов этих эффектов.

Ссылочная прозрачность

Отсутствие побочных эффектов - необходимое, но недостаточное условие ссылочной прозрачности. Ссылочная прозрачность означает, что выражение (например, вызов функции) может быть заменено его значением. Для этого требуется, чтобы выражение было чистый, то есть выражение должно быть детерминированный (всегда давай то же самое ценить для того же входа) и без побочных эффектов.

Временные побочные эффекты

Побочные эффекты, вызванные временем, затраченным на выполнение операции, обычно игнорируются при обсуждении побочных эффектов и ссылочной прозрачности. В некоторых случаях, например, с аппаратным синхронизацией или тестированием, операции вставляются специально из-за их временных побочных эффектов, например сон (5000) или же for (int i = 0; i <10000; ++ i) {}. Эти инструкции не изменяют состояние, за исключением времени для выполнения.

Идемпотентность

Функция ж с побочными эффектами считается идемпотентным при последовательной композиции f; ж если при двойном вызове с одним и тем же списком аргументов второй вызов не имеет побочных эффектов и возвращает то же значение, что и первый вызов[нужна цитата ] (при условии, что никакие другие процедуры не вызывались между концом первого вызова и началом второго вызова).

Например, рассмотрим следующие Python код:

Икс = 0def Setx(п):    Глобальный Икс    Икс = пSetx(5)Setx(5)

Здесь, Setx идемпотентен, потому что второй вызов Setx (с тем же аргументом) не изменяет видимое состояние программы: Икс был уже установлен в 5 в первом вызове и снова установлен в 5 во втором вызове, таким образом сохраняя то же значение. Обратите внимание, что это отличается от идемпотентность под функциональным составом f ∘ f. Например, абсолютная величина идемпотентна относительно композиции функций:

def пресс(п):    если п < 0:        возвращаться -п    еще:        возвращаться ппресс(-5) == пресс(пресс(-5)) == пресс(5) == 5

Пример

Одна из распространенных демонстраций поведения побочных эффектов - это оператор присваивания в C ++. Например, присвоение возвращает правильный операнд и имеет побочный эффект присвоения этого значения переменной. Это позволяет синтаксически чистое множественное присваивание:

int я, j;я = j = 3;

Потому что оператор правильные партнеры, это приравнивается к

int я, j;я = (j = 3);  // j = 3 возвращает 3, которое затем присваивается i

Где результат отнесения 3 к j затем назначается в я. Это может привести к зависанию начинающих программистов, которые могут запутать

пока (б == 10) {}  // проверяет, оценивается ли b как 10

с

пока (б = 10) {}  // = возвращает 10, которое автоматически принимает значение true, поэтому проверка всегда выполняется

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

Рекомендации

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