stringtranslate.com

Побочный эффект (информатика)

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

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

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

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

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

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

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

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

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

Подпрограмма с побочными эффектами является идемпотентной, если несколько применений подпрограммы оказывают такое же влияние на состояние системы, как и одно применение, другими словами, если функция из пространства состояний системы в себя, связанная с подпрограммой, идемпотентна в математическом смысле . Например, рассмотрим следующую программу Python :

х  =  0def  setx ( n ):  глобальный  x  x  =  nsetx ( 3 ) утверждать  x  ==  3 setx ( 3 ) утверждать  x  ==  3

setxявляется идемпотентным, поскольку второе применение setxзначения 3 оказывает тот же эффект на состояние системы, что и первое применение: xуже было установлено значение 3 после первого применения, и оно все еще установлено на 3 после второго применения.

Чистая функция идемпотентна, если она идемпотентна в математическом смысле . Например, рассмотрим следующую программу Python:

def  abs ( n ):  return  - n,  если  n  <  0  , иначе  nутверждать  абс ( абс ( - 3 ))  ==  абс ( - 3 )

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

Пример

Одной из распространенных демонстраций поведения побочных эффектов является оператор присваивания в C. Присваивание a = b— это выражение, результатом которого является то же значение, что и выражение b, с побочным эффектом сохранения R-значения в bL - значении a. Это позволяет множественное назначение:

а = ( б = 3 ); // b = 3 оценивается как 3, которое затем присваивается     

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

а = б = 3 ;    

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

while ( b == 3 ) {} // проверяет, имеет ли значение b значение 3     

с

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

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

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

  1. ^ Спулер, Дэвид А.; Саджив, А. Сайед Мухаммед (январь 1994 г.). Обнаружение компилятором побочных эффектов вызова функций . Университет Джеймса Кука . CiteSeerX  10.1.1.70.2096 . Термин «побочный эффект» относится к модификации нелокальной среды. Обычно это происходит, когда функция (или процедура) изменяет глобальную переменную или аргументы, передаваемые ссылочными параметрами. Но есть и другие способы изменения нелокальной среды. Мы рассматриваем следующие причины побочных эффектов при вызове функции: 1. Выполнение ввода-вывода. 2. Изменение глобальных переменных. 3. Изменение локальных постоянных переменных (например, статических переменных в C). 4. Изменение аргумента, передаваемого по ссылке. 5. Изменение локальной переменной, автоматической или статической, функции, расположенной выше в последовательности вызова функции (обычно с помощью указателя).
  2. ^ Тернер, Дэвид А. , изд. (1990). Темы исследований по функциональному программированию . Аддисон-Уэсли . стр. 17–42.Через Хьюза, Джон. «Почему функциональное программирование имеет значение» (PDF) . Архивировано (PDF) из оригинала 14 июня 2022 г. Проверено 6 августа 2022 г.
  3. ^ Коллберг, Кристиан С. (22 апреля 2005 г.). «CSc 520 Принципы языков программирования». Департамент компьютерных наук Университета Аризоны . Архивировано из оригинала 06 августа 2022 г. Проверено 6 августа 2022 г.
  4. ^ "Отчет Haskell 98" . 1998.
  5. ^ Джонс, Саймон Пейтон; Уодлер, Фил (1993). Императивное функциональное программирование . Протокол конференции 20-го ежегодного симпозиума ACM по принципам языков программирования. стр. 71–84.
  6. ^ Феллизен, Матиас ; Финдлер, Роберт Брюс; Флэтт, Мэтью; Кришнамурти, Шрирам (1 августа 2014 г.). «Как разрабатывать программы» (2-е изд.). МТИ Пресс .