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)
Ответ на: комментарий от xmikex

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

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

Процедура, ещё раз подчёркиваю, не может иметь никаких побочных эффектов по определению

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

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

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

xmikex ★★★★
()

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

Автор немножко путает тёплое с мягким. Побочный эффект есть в обоих случаях, но для функции это плохо, а для процедуры в основном наплевать и вообще она ради этого задумана. Суть в том, что функция может быть частью выражения и т.о. грязная функция будет менять результат вычисления выражения в зависимости от фаз Луны. Поэтому не стоит писать грязные функции, иначе 2+2 будет 42, а синус достигать 4. Процедуры изначально задуманы как «гигиеничные» подпрограммы, т.е. в отличие от суровых подпрограмм из каменного века, процедура имеет чётко заданный набор данных над которыми производится действие (в т.ч. по-месту), нельзя делать goto в астрал и т.п. ограничения которые образуют основу так называемого «процедурного программирования». Понятие побочного эффекта и чистоты по этой причине к процедурам-подпрограммам не вполне применимо. Но автор захотел натянуть сову на глобус и придумал своё оригинальное определение.

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

для него просто побочные - синоним нежелательных

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

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

Как никто? Вон, Мигуэль прискакал верхом на монаде. Обычно всё, что он пишет, несет на себе след употребления тяжелых наркотиков^W^W хаскеля.

Virtuos86 ★★★★★
()
Ответ на: комментарий от no-such-file

и вообще она ради этого задумана.

Прошу простить дурака за, возможно, идиотский вопрос, но: если она ради этого задумана, то зачем называть это побочным еффектом?

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

зачем называть это побочным еффектом

Незачем. Ну т.е. можно, но бессмысленно.

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

Я отвечал на сообщение о том, что у слова side, якобы, нет значения второстепенный, вторичный.

Однако по мной приведенной ссылке показано, что сочетание side effect в общем случае мыслится именно как эффект, вторичный по отношению к какому-то основному. Это полностью согласуется с трактовкой Столярова.

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

Однако по мной приведенной ссылке показано, что сочетание side effect в общем случае

Я бы сказал «в бытовом употреблении».

Это полностью согласуется с трактовкой Столярова.

Только вот в специальной технической области нужно пользоваться соответствующими определениями, а не бытовыми. Плюс, в стандартах C и C++ вводится своё определение для side effect.

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

Далеко не только в бытовом, а, например, ещё и в медицине. Но дело не в этом. Ещё разок - в сообщении, на которое я отвечал, утверждалось, что слово side вообще не имеет такого значения (а потому, если бы имелось в виду это значение, то, якобы, употреблялось бы «collateral effects» или как-то ещё). Я ответил, что это неправда. Ну а спорить со стандартами - ни как сторонник, ни как противник - я не буду.

anonymous
()
17 августа 2022 г.
Ответ на: комментарий от wandrien

Что там автор пытается навесить тень на плетень, приписав, что ввод-вывод - «это другое», оставим на совести автора.

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

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

В целом на C можно имитировать это соглашение, но с некоторыми оговорками, понять которые сишникам будет трудно, поэтому стоит начинать изучать программирование не с C, а например, с паскаля.

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

Ну т.е. если я пишу функцию print_hello(), то вывод в ней - это все равно побочный эффект?

Т.е. дело тут чисто в формулировках? В C функции - это не функции, а процедуры, которые могут возвращать результат?

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

Ну т.е. если я пишу функцию print_hello(), то вывод в ней - это все равно побочный эффект?

То это уже не функция, а процедура. Впрочем в C можно искусственно создать различие между функциями и процедурами, если в функция с возвращаемым значением избегать побочных эффектов, а все процедуры делать типа void. Если понадобится вернуть значение из процедуры, можно применить возврат по ссылке (указателю).

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

А вообще почему бы тебе не прочитать учебник Столярова, а не мои попытки его пересказать?

Xenius ★★★★★
()
Последнее исправление: Xenius (всего исправлений: 2)
    write('Enter H: ');
    readln(h)

это уже побочный эффект.

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

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

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

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

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

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

Чем функция на C, «возвращающая» void отличается от процедуры?

Туда же вопрос, чем в паскале процедура с var-параметром (который возвращает значение) отличается от функции?

vbr ★★★★
()
Последнее исправление: vbr (всего исправлений: 1)

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

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

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

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

Чем функция на C, «возвращающая» void отличается от процедуры?

Названием! Но можно считать это аналогом процедуры.

Туда же вопрос, чем в паскале процедура с var-параметром (который возвращает значение) отличается от функции?

Семантикой. Вот в машинном коде например цикл превращается в конструкцию из услового перехода и goto (jmp). И можно подобрать конструкцию с goto вместо цикла в языке, так что она будет давать тот же результат, но семантически она отличается от нормального цикла (while, for, repeat), не смотря на одинаковое представление в машинном коде.

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

побочные эффекты не перестают ими быть.

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

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

Вообще-то можно, так обычно и говорят.

Но это всё споры не по существу, а об определениях.

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