Я не совсем понял концепцию побочного эффекта.
- Что такое побочный эффект в программировании?
- Это зависит от языка программирования?
- Есть ли такая вещь, как внешние и внутренние побочные эффекты?
Пожалуйста, приведите пример причин, которые создают побочные эффекты.
programming-languages
functional-programming
Амир Резаи
источник
источник
Ответы:
Побочный эффект относится просто к изменению некоторого состояния - например:
Вопреки тому, что некоторые люди, кажется, говорят:
Побочный эффект не должен быть скрытым или неожиданным (это может быть, но это не имеет ничего общего с определением, которое применяется к информатике);
Побочный эффект не имеет ничего общего с идемпотентностью. Идемпотентная функция может иметь побочные эффекты, а неидемпотентная функция может не иметь побочных эффектов (например, получение текущей системной даты и времени).
Это действительно очень просто. Побочный эффект = что-то меняется.
PS Как указывает комментатор Бенджол, несколько человек могут смешивать определение побочного эффекта с определением чистой функции , которая является (а) идемпотентной и (б) не имеет побочных эффектов. Один не подразумевает другого в общей компьютерной науке, но функциональные языки программирования, как правило, имеют тенденцию усиливать оба ограничения.
источник
++a
. Не похоже на назначение.b = ++a;
имеет два побочных эффекта. Очевидное и крипто-назначениеa
. Это та вещь, которая является побочным эффектом, который (для некоторых) желателен. Но за всю мою карьеру это назвали побочным эффектом, чтобы сделать его не тонким.Говорят, что любая операция, которая изменяет состояние компьютера или взаимодействует с внешним миром, имеет побочный эффект. Смотрите Википедию о побочных эффектах .
Например, эта функция не имеет побочных эффектов. Его результат зависит только от входных аргументов, и при вызове ничего не меняется в состоянии программы или ее окружения:
Напротив, вызов этих функций даст вам разные результаты в зависимости от порядка их вызова, потому что они что-то меняют в состоянии компьютера:
Эта функция имеет побочный эффект записи данных для вывода. Вы не вызываете функцию, потому что хотите получить возвращаемое значение; Вы называете это потому, что хотите, чтобы эффект, который он оказывает на «внешний мир»:
источник
Write
показывает ваш пример, наличие побочных эффектов не означает, что функция когда-либо меняет свой вывод относительно своих входов, или даже что ее выход вообще зависит от входа.square(x)
может привести к загрузке модуля, в котором определена функция, с диска. Должно ли это считаться побочным эффектом? В конце концов, это тот факт, что (первый) вызов занимает неожиданно много времени,square(x)
потому что хотите, чтобы состояние внешнего компьютера изменилось, вы можете считать это побочным эффектом.Я думаю, что существующие ответы довольно хороши. Я хотел бы остановиться на некоторых аспектах, которые IMO недостаточно подчеркнули.
В математике функция - это просто отображение кортежа значений в значение. Так что, учитывая функцию
f
и значениеx
,f(x)
всегда будет один и тот же результатy
. Вы вполне можете заменитьf(x)
наy
везде в выражении, и ничего не изменится.То, что во многих языках программирования называется функцией (или процедурой), является конструкцией (частью кода), которая может быть выполнена, потому что:
Таким образом, эффекты могут быть связаны с состоянием, но также и с другими аспектами, такими как запуск ракеты или приостановка выполнения на несколько секунд.
Термин «побочный эффект» может звучать отрицательно, но обычно эффект вызова функции является самой целью самой функции. Я предполагаю, что, поскольку термин «функция» изначально использовался в математике, вычисление значения считается основным эффектом функции, тогда как любые другие эффекты считаются побочными эффектами . Некоторые языки программирования используют термин процедура, чтобы избежать путаницы с функциями в математическом смысле.
Обратите внимание, что
sleep()
в Python, полезны только для их (побочных) эффектов. Они часто моделируются как функции, которые возвращают специальное значениеNone
, илиunit
или()
или ..., которое просто указывает, что вычисление завершено правильно.источник
Побочный эффект - это когда операция оказывает влияние на переменную / объект, который находится за пределами предполагаемого использования.
Это может произойти, когда вы вызываете сложную функцию, побочным эффектом которой является изменение некоторой глобальной переменной, даже если вы не вызвали ее (возможно, вы вызвали ее для извлечения чего-либо из базы данных).
Я признаю, что мне трудно придумать простой пример, который не выглядит полностью надуманным, а примеры из того, над чем я работал, слишком длинны, чтобы их можно было здесь разместить (и, поскольку это связано с работой, мне, вероятно, не следует в любом случае ).
Одним примером, который я видел (некоторое время назад), была функция, которая открывала соединение с базой данных, если соединение было в закрытом состоянии. Проблема заключалась в том, что предполагалось закрыть соединение в конце функции, но разработчик забыл добавить этот код. Итак, здесь был непреднамеренный побочный эффект: при вызове процедуры должен был выполняться только запрос, и побочным эффектом было то, что соединение оставалось открытым, и если функция вызывалась дважды подряд, возникла бы ошибка, сообщающая, что соединение было уже открыт.
Хорошо, так как все сейчас приводят примеры, я думаю, что я тоже буду;)
Функция
do_task_x
имеет основной эффект возврата результата некоторых вычислений и побочный эффект возможного изменения глобальной переменной.Разумеется, что является основным, а побочный эффект может быть открытым для интерпретации и может зависеть от фактического использования. Если я вызываю эту функцию с целью изменения глобального и отбрасываю возвращаемое значение, то я бы сказал, что изменение глобального является основным эффектом.
источник
Из Википедии - Побочный эффект
Функция, в математическом смысле, является отображением ввода-вывода. Предполагаемый эффект вызова функции - сопоставить входные данные с выходными данными, которые она возвращает. Если функция делает что-то еще, не имеет значения, что, но если у нее есть какое-либо поведение, которое не отображает входные данные на выход, это поведение, как известно, является побочным эффектом.
В более общем смысле, побочным эффектом является любой эффект, который не является предполагаемым эффектом дизайнера конструкции.
Эффект - это все, что влияет на актера. Если я вызываю функцию, которая отправляет моей девушке текстовое сообщение о разрыве, которое затрагивает группу актеров, меня, ее, сеть компании сотовой связи и т. Д. Единственный предполагаемый эффект вызова функции, свободной от побочных эффектов, - это функция вернуть мне отображение из моего ввода. Таким образом, для:
Если это предназначено для функции, то единственное, что нужно сделать, это вернуть void. Если он не имеет побочных эффектов, он не должен отправлять текстовое сообщение.
В большинстве языков программирования нет конструкции для математической функции. Ни одна конструкция не предназначена для использования в качестве таковой. Вот почему большинство языков говорят, что у вас есть методы или процедуры. По замыслу, они предназначены для того, чтобы иметь возможность делать гораздо больше эффектов. На обычном языке программирования никто не заботится о том, каким был метод или процедура, поэтому, когда кто-то говорит, что эта функция имеет побочный эффект, они фактически подразумевают, что эта конструкция не ведет себя как математическая функция. И когда кто-то говорит, что эта функция не имеет побочных эффектов, они подразумевают, что эта конструкция эффективно ведет себя как математическая функция.
Чистая функция всегда свободна от побочных эффектов по определению. Чистая функция, это способ сказать, что эта функция, даже несмотря на то, что она использует конструкцию, которая допускает большее количество эффектов, имеет эффект, равный эффекту математической функции.
Я призываю любого сказать мне, когда функция без побочных эффектов не будет чистой. Если основной предполагаемый эффект контекста предложения, использующего термин чистый и свободный побочный эффект, не является эффектом математического предполагаемого эффекта функции, то они всегда равны.
Таким образом, иногда, хотя и реже, и я полагаю, что это различие отсутствует, а также вводит в заблуждение людей (поскольку это не самое распространенное предположение) в принятом ответе, но иногда предполагается, что предполагаемый эффект функции программирования сопоставить ввод с выводом, где ввод не ограничен явными параметрами функции, но вывод ограничен явным возвращаемым значением. Если вы предполагаете, что это предполагаемый эффект, то функция, считывающая файл и возвращающая другой результат в зависимости от того, что находится в файле, по-прежнему не имеет побочных эффектов, так как вы позволили входным данным поступать из других мест в вашем предполагаемом эффекте.
Итак, почему это все важно?
Это все о контроле и сохранении. Если вы вызываете функцию, и она делает что-то еще, а затем возвращает значение, трудно понять ее поведение. Вам нужно будет заглянуть внутрь функции для реального кода, чтобы угадать, что он делает, и подтвердить его правильность. Идеальная ситуация заключается в том, что очень ясно и легко узнать, какой ввод использует функция, и что она больше ничего не делает, затем возвращает вывод для нее. Вы можете немного расслабиться и сказать, что точно знать, какой ввод он использует, не так полезно, как быть уверенным, что он не делает ничего другого, о чем вы можете не знать, а затем вернуть значение, так что, возможно, вы удовлетворены только принудительным применением что он не делает ничего другого, кроме отображения входных данных, независимо от того, откуда он их получает, для вывода.
Практически во всех случаях смысл программы состоит в том, чтобы иметь эффекты, отличные от сопоставления вещей, входящих в исходящие вещи. Идея управления побочным эффектом заключается в том, что вы можете организовать код так, чтобы его было легче понять и обдумать. Если вы соберете все побочные эффекты вместе, в месте, которое является очень явным и центральным, легко узнать, где искать и верить, что это все, что происходит, не более. Если у вас также очень явный ввод, это помогает проверить поведение для другого ввода, и его проще использовать, так как вам не нужно менять ввод во многих разных местах, некоторые из которых могут быть неочевидными, просто чтобы получить то, что вы хотите.
Поскольку наиболее полезным для понимания, обоснования и управления поведением программы является то, чтобы все входные данные были четко сгруппированы вместе и явными, а также чтобы все побочные эффекты были сгруппированы вместе и явными, об этом обычно говорят люди, когда говорят побочный эффект, чистый и т. д.
Поскольку наиболее полезным является группировка побочных эффектов и их явность, иногда люди будут только подразумевать это и различать это, говоря, что это не чисто, но все же «побочный эффект» свободен. Но побочный эффект относится к предполагаемому «предполагаемому первичному эффекту», поэтому это контекстуальный термин. Я считаю, что это используется реже, хотя на удивление много говорится в этой теме.
Наконец, идемпотент означает, что вызов этой функции много раз с одними и теми же входами (независимо от того, откуда они берутся) всегда будет приводить к одинаковым эффектам (побочный эффект или нет).
источник
При программировании побочный эффект - это когда процедура изменяет переменную вне ее области видимости. Побочные эффекты не зависят от языка. Есть несколько классов языков, которые нацелены на устранение побочных эффектов (чисто функциональные языки), но я не уверен, есть ли такие, которые требуют побочных эффектов, но я могу ошибаться.
Насколько я знаю, внутренних и внешних побочных эффектов нет.
источник
Вот простой пример:
Определение побочного эффекта не является специфическим для программирования, поэтому просто представьте себе побочные эффекты ваших лекарств или употребление слишком большого количества пищи.
источник
x++
изменяет переменнуюx
, обычно считается побочным эффектом. Это значение выражения является значением перед приращениемx
; это часть побочного эффекта выражения.Побочным эффектом являются вещи, которые происходят в коде, которые не являются очевидными.
Например, допустим, у вас есть этот класс
Когда вы изначально создаете класс, вы даете ему семя.
Вы не знаете внутренности, вы просто ожидаете получить случайное значение, и вы ожидаете, что randomGenerator.Seed все равно будет 15 ... но это не так.
У вызова функции был побочный эффект изменения значения Seed.
источник