Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

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

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

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

Ссылочная прозрачность [ править ]

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

Временные побочные эффекты [ править ]

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

Идемпотенция [ править ]

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

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

х  =  0def  setx ( n ):  глобальный  x  x  =  nнабор x ( 5 ) набор x ( 5 )

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

def  abs ( n ):  if  n  <  0 :  return  - n  else :  return  nабс ( - 5 )  ==  абс ( абс ( - 5 ))  ==  абс ( 5 )  ==  5

Пример [ править ]

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

int  i ,  j ; я  =  j  =  3 ;

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

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

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

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

с участием

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

См. Также [ править ]

  • Действия на расстоянии (компьютерное программирование)
  • Срок безразличия
  • Точка последовательности
  • Атака по побочному каналу

Ссылки [ править ]

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