LINUX.ORG.RU

Побочные эффекты функций

 , ,


3

1

В первом томе свого монументального труда А.В. Столяров пытается мне донести опасность побочных эффектов, приводя в пример функции и процедуры Pascal. И как C плох тем, что в нем только функции. В своем интерьвю он тоже про это упоминает.

Но я ничего не понел.

Возьмем его же пример свободной от побочных эффектов процедуры:

procedure NegotiateSize(var res: integer);
var
  h: integer;
begin
  repeat
    write('Enter H: ');
    readln(h)
  until (h > 0) and (h mod 2 = 1);
  res := h
end;

И аналогичную функцию с побочным эффектом:

function NegotiateSize: integer;
var
  h: integer;
begin
  repeat
    write('Enter H: ');
    readln(h)
  until (h > 0) and (h mod 2 = 1);
  NegotiateSize := h
end;

Объясните мне, где тут побочный эффект?

p.s. почему подсветка кода ломается на функции?

★★★★★

Последнее исправление: Turbid (всего исправлений: 3)
Ответ на: комментарий от MPH

Книги Столярова могут полезны разве что для школьников, если рассматривать их в общеобразовательном научно-популярном ключе.

anonymous
()
Ответ на: комментарий от anonymous

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

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

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 2)
Ответ на: комментарий от Turbid

Там же написано всё

В целом это пример того, как не надо делать

и там же написано в чём «побочность» эффектов, которых два:

  • ввод-вывод внутри
  • использование параметра-переменной для передачи введёных значений
vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 2)
Ответ на: комментарий от vvn_black

а зачем написано, что если мы будем возвращать из функции логическое значение, то станет источником побочных эффектов? причём тут возвращение значения из функции?

xmikex ★★★★
()
Ответ на: комментарий от xmikex

Кмк, тут сложный слог, а смысл такой, можно сократить количество кода, но побочные эффекты никуда не денутся. Но, я не уверен, что автор имел в виду именно это.

Т.е. превратить процедуру в функцию для читаемости, а не для избавления от сайд эффектов.

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)
Ответ на: комментарий от vvn_black

ввод-вывод внутри

А внутри процедуры разве нет ввода-вывода?! и да, дело же не вводе-выводе: Побочные эффекты функций (комментарий)

использование параметра-переменной для передачи введёных значений

это в процедуре, которая у него лишена побочного эффекта.

Turbid ★★★★★
() автор топика
Последнее исправление: Turbid (всего исправлений: 1)
Ответ на: комментарий от vvn_black

Т.е. превратить процедуру в функцию для читаемости, а не для избавления от сайд эффектов.

Нет, именно не рекомендует использовать функцию, т.к. в ней побочные эффекты!

Turbid ★★★★★
() автор топика
Ответ на: комментарий от Turbid

и да, дело же не вводе-выводе

там же в твоём комментарии есть скрин, где написано

или присваивания каким-то переменным, кроме своих локальных

тут в обсуждении последние две страницы как раз об этом, что использование параметра-переменной - это и есть побочный эффект.

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

vvn_black ★★★★★
()
Ответ на: комментарий от Turbid

Ну, всё здраво и разумно здесь.

Повторюсь, почему он к процедурам делает особый подход - ХЗ.

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)
Ответ на: комментарий от vvn_black

Почему автор не считает таковым эффект в процедуре?

Вот это главный, собственно вопрос. Кто мне мешает присваивать что угодно и менять среду внутри процедуры? Как она меня уберегает от побочных эффектов?

Turbid ★★★★★
() автор топика
Ответ на: комментарий от Turbid

Я думаю - это опять косноязычие изложения.

Раз функция возвращает результат, то она и должна так делать, без всяких сайд эффектов. По своей природе.

А раз процедура ничего не возвращает, то для неё позволительно менять параметры-переменные. По совей природе.

Это вот такие мои догадки.

vvn_black ★★★★★
()
Ответ на: комментарий от MPH

Оба представляют. Для психиатрии.

anonymous
()
Ответ на: комментарий от Turbid

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

xmikex ★★★★
()
Ответ на: комментарий от xmikex

А если есть возврат значения - получается функция с побочным эффектом.

Ну нет, же. В скринах речь идёт об эффекте, когда функция меняет параметр-переменную, а не возвращает значение.

vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

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

xmikex ★★★★
()
Ответ на: комментарий от Turbid

Какая разница?
Суть в том, что в паскаль функция и процедура разные понятия.
Я так понял, что вся идея автора там такая - надо вносить побочные эффекты - пишите процедуры, побочных эффектов нет - пишите функции.

xmikex ★★★★
()
Ответ на: комментарий от xmikex

Разные-то они разные, и Хоар с Виртом в «аксиоматике Паскаля» писали, что все их выкладки для функций подразумевают отсутствие в функциях побочных эффектов. И вообще хорошо бы компиляторы это проверяли, но давайте не будем обязывать компиляторы проводить такие проверки.

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

anonymous
()
Ответ на: комментарий от Turbid

Процедура ничего не возвращает в место вызова, void-функция возвращает «ничего».

Minona ★★☆
()
Ответ на: комментарий от Crocodoom

Общепринятое можешь посмотреть в википедии, и ввод-вывод там упомянут

Английский знаешь? Ну так иди читай английскую статью той же Википедии: https://en.wikipedia.org/wiki/Side_effect_%28computer_science%29

Ну так, спойлер: она начинается с фразы «In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, that is to say has an observable effect besides returning a value (the intended effect) to the invoker of the operation»

А русский раздел википедии, по крайней мере практически всё, что там есть про программирование, написано троечниками, не знающими предмета.

Croco ★★★
()
Ответ на: комментарий от annulen

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

Если ввод-вывод производится НЕ в ходе вычисления выражения, то, разумеется, побочным эффектом он не является. А ещё, увы, мой опыт показывает, что сишность головного мозга не лечится.

Croco ★★★
()
Ответ на: комментарий от xmikex

вся идея автора там такая - надо вносить побочные эффекты - пишите процедуры,

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

Croco ★★★
()
Последнее исправление: Croco (всего исправлений: 1)
Ответ на: комментарий от Croco

Если ввод-вывод производится НЕ в ходе вычисления выражения, то, разумеется, побочным эффектом он не является.

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

Turbid ★★★★★
() автор топика
Ответ на: комментарий от Croco

Ну так, спойлер: она начинается с фразы …

А продолжается фразой «Example side effects include … performing I/O»

anonymous
()
Ответ на: комментарий от Croco

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

Речь вообще не о побочных эффетках процедуры или функции, а об общем понятии побочные эффекты вычислений. Процедура - создаётся для выполнения побочных эффектов по мере вычислений. Функция - создаётся для вычисления возвращаемого результата и она может быть свободна или несвободна от побочных эффектов. Для процедуры выражение употреблять свободна от побочных эффектов - нонсенс.

xmikex ★★★★
()
Последнее исправление: xmikex (всего исправлений: 1)
Ответ на: комментарий от Turbid

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

Ы! Ну я уж даже прям и не знаю.

Так-с, наиболее популярно у нас второе издание от МАКС Пресс, так что номера страниц будут по нему. В PDF-файлах, напомню, номера страниц отличаются из-за наличия обложки и лицензии.

Для начала «предисловие второе, методическое», стр. 31, подробное рассуждение на эту тему, причём фраза «побочный эффект может возникнуть только при вычислении выражения» выделено жирным шрифтом.

Потом в самом начале главы про подпрограммы есть (на стр. 285) небольшой абзац мелким шрифтом про искажение мышления. Между прочим, весь этот тред представляет собой шикарную иллюстрацию на эту тему.

Дальше имеется специально посвящённый этой теме параграф 2.3.6, и тоже нужная фраза (на этот раз стр. 299) выделена жирным.

Насколько я помню, в первом томе есть ещё пара упоминаний побочных эффектов, одно вы тут уже цитировали (это где циклы с пустыми телами), другое в связи с функцией ReadKey из модуля crt (увы). Дальше там ассемблер, в нём побочных эффектов не бывает (вообще, совсем, никак, никогда, ибо нет выражений, вычисляемых в рантайме). Поэтому бросаем первый том и берём второй.

Побочные эффекты упоминаются в рассказе о Си неоднократно (оно и понятно), но систематическое рассуждение о них вынесено в параграф 4.8.3, который так и называется «Побочные эффекты» (а целиком глава 4.8 посвящена стилю кода). Жирным в этот раз нужное замечание не выделено, но оно тут прямо во втором абзаце. Заодно рассказано, как отделить одни побочные эффекты (обусловленные либо самим языком Си, либо структурой программы) от других (неуместных трюков). Имею наглость утверждать, что лица, не имеющие опыта работы на Паскале, этот текст просто не поймут, и, собственно, это и есть то, ради чего столь тщательно акцентируются побочные эффекты в части «про Паскаль».

Ну и, наконец, в третьем томе, посвящённом парадигмам программирования, опять же имеется целый параграф (9.3.2, «Концептуальное отличие Си от Паскаля», стр.68). Здесь опять же нужные фразы про побочные эффекты, появляющиеся на стр.70, выделены жирным шрифтом.

Мне, пардон, какую ещё формулировку привести прикажете?

А, да, ещё один хинт: все эти страницы можно найти, если в конце третьего тома таки заметить предметный указатель и посмотреть там термин «побочный эффект».

Croco ★★★
()
Ответ на: комментарий от Croco

Дальше там ассемблер, в нём побочных эффектов не бывает

Открываем твою ссылку на английскую википедию: «Assembly language programmers must be aware of hidden side effects …»

anonymous
()
Ответ на: комментарий от xmikex

К чему писать слова свободная от побочных эффектов процедура?

Я такого никогда не писал, разумеется. Процедура, ещё раз подчёркиваю, не может иметь никаких побочных эффектов по определению. А ваш (ущербный и недопустимый, я настаиваю на этом) подход к термину «побочный эффект» лишает термин смысла, а заодно отнимает инструмент для объяснения, почему, например, за while(~wait(NULL)); надо с работы выгонять.

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

Croco ★★★
()
Ответ на: комментарий от anonymous

performing I/O

Разумеется, ввод-вывод – прекрасный пример побочного эффекта, коль скоро производится из «операции, выражения или функции», как там сказано фразой назад.

Впрочем, википедия не авторитет, просто забавно, что в английской хоть что-то осмысленное написано, а в русской просто бред.

Croco ★★★
()
Ответ на: комментарий от anonymous

hidden side effects

Там другая предметная область, хотя и родственная; и в ней своя терминология, поскольку исходный термин «побочный эффект» там не занят – на уровне машинных команд нет побочных эффектов в классическом смысле.

Croco ★★★
()
Ответ на: комментарий от Croco

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

xmikex ★★★★
()
Ответ на: комментарий от Croco

Учим доучек пользоваться Википедией.

In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, that is to say has an observable effect besides returning a value (the intended effect) to the invoker of the operation. State data updated «outside» of the operation may be maintained «inside» a stateful object or a wider stateful system within which the operation is performed. Example side effects include modifying a non-local variable, modifying a static local variable, modifying a mutable argument passed by reference, performing I/O or calling other side-effect functions.[1]

Читаем сноску [1] на которой основан данный абзац

Spuler, David A.; Sajeev, A. S. M. (January 1994). Compiler Detection of Function Call Side Effects. James Cook University. CiteSeerX 10.1.1.70.2096. The term Side effect refers to the modification of the nonlocal environment. Generally this happens when a function (or a procedure) modifies a global variable or arguments passed by reference parameters. But here are other ways in which the nonlocal environment can be modified. We consider the following causes of side effects through a function call: 1. Performing I/O. 2. Modifying global variables. 3. Modifying local permanent variables (like static variables in C). 4. Modifying an argument passed by reference. 5. Modifying a local variable, either automatic or static, of a function higher up in the function call sequence (usually via a pointer).

javascript
()
Ответ на: комментарий от xmikex

Какой смысл не называть изменения вносимые процедурой во внешний мир побочными эффектами?

Нет, вы лучше мне объясните, какой смысл называть (!) побочным (!) эффектом то, ради чего процедура написана (она же ни для чего больше не нужна, кроме таких изменений), особенно если учесть, что – ещё раз подчёркиваю – такой подход к терминологии попросту убивает термин «побочный эффект», делает его полностью бессмысленным, тогда как в его исконном смысле он не просто полезен, а представляет собой единственное (по крайней мере известное мне) средство объяснения, чем плохи неуместные трюки.

Дальнейшую конкретику можете в книжке прочитать, книжки, если что, вот тут дают: http://www.stolyarov.info/books/programming_intro/e2 Я не готов тут в сотый раз повторять аргументы, которые уже 99 раз повторял и которые подробно рассмотрены в книге.

Croco ★★★
()
Ответ на: комментарий от javascript

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

xmikex ★★★★
()
Ответ на: комментарий от xmikex

Побочный эффект нельзя «внести», его можно иметь или не иметь, и это только свойство выражения, а не чего-либо ещё.

А, да, недоучки бывают и англоговорящие тоже, забыл об этом упомянуть.

Croco ★★★
()
Ответ на: комментарий от Croco

У слова side нет значения в смысле второстепенный, их бы назвали collateral effects, если бы побочными их называли в вашем смысле.

xmikex ★★★★
()
Ответ на: комментарий от Croco

Момент, когда выполняется функцией во внешнем окружении изменений - это как назывется по-вашему?

xmikex ★★★★
()
Ответ на: комментарий от Croco

все эти страницы можно найти, если в конце третьего тома таки заметить предметный указатель

Это потрясающе удобно, но я привык по стариковски - поиском. Но он в вашей PDF, увы, не робит из-за кодировки.

Turbid ★★★★★
() автор топика
Ответ на: комментарий от xmikex

Текстовый слой в PDF-файлах, представленных на этом сайте, преднамеренно сломан. Рекомендую воспринимать эти файлы как аналог бумажной книги, только без бумаги. В бумажных книгах тоже нет ни поиска, ни возможности копирования в конспект.

Croco ©

Turbid ★★★★★
() автор топика
Последнее исправление: Turbid (всего исправлений: 1)
Ответ на: комментарий от Croco

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

Это справедливо для паскакаля, но для большинства ЯП, на которых и будут писать ваши студенты, нет разделения на процедуры и функции. По-моему из-за этого и возник спор.

goingUp ★★★★★
()
Ответ на: комментарий от Turbid

Текстовый слой в PDF-файлах, представленных на этом сайте, преднамеренно сломан. Рекомендую воспринимать эти файлы как аналог бумажной книги, только без бумаги. В бумажных книгах тоже нет ни поиска, ни возможности копирования в конспект.

Я б такое не купил)

goingUp ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.