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)

Как только увидел заголовок, сразу подумал «Чел Столярова читает, походу» =)

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

Насчет прримера я хз.

Zhbert ★★★★★
()

Who hate the word procedure, write in C!

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

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

Я всю жизнь думал что функция с void в C == процедуре в Pascal.

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

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

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

Любой ЯП располагает думать о таких вещах, чтобы не писать говнокод.

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

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

Копипаста из его книги не работает, поэтому приведу его ответ вам в виде скриншота

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

Примеры неверные. Здесь есть ввод-вывод, значит и побочные эффекты.

см. выше

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

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

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

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

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

Выглядит не очень. Но раз речь идёт о побочных эффектах функции, то у процедуры не может быть «побочного эффекта функции» - это ж процедура, а не функция! То есть всё это софистика какая-то.

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

Если у аффтора какое-то своё понимание «побочных эффектов», отличающееся от общепринятого, то не мешало бы его привести.

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

https://ru.wikipedia.org/wiki/Побочный_эффект_(программирование)

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

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

А давайте спросим начальника транспортного цеха Croco

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

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

Копипаста из его книги не работает,

Уже в этом месте стоило бы оставить эту книгу. Автор не уважает читателя.

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

понапридумывают херни, а потом divmod() не могут заинлайнить из-за этого

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

реального опыта проектирования софта и создания продуктивного кода у него нет

в интервью он утверждает обратное

Автор не уважает читателя.

будем снисходительны к авторскому стилю

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

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

Если функция читает и изменяет что-то, что не является её аргументами или возвращаемым значением, то она, фактически, имеет «скрытые аргументы», не входящие в её декларацию.

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

Достаточно провести мысленный эксперимент:

  • Функция A обнуляет глобальную переменную foo. Функция B инкрементирует foo и возвращает новое значение.
  • Функция A обнуляет содержимое файла foo. Функция B инкрементирует содержимое файла foo и возвращает новое значение.

В обоих случаях мы имеем дело с побочными эффектами.

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

Как только увидел заголовок, сразу подумал «Чел Столярова читает, походу» =)

Что?

ЕМНИП, побочный эффект — это выполнение лишних действий

Чта?

Побочный эффект — изменение среды выполнения.

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

НеСИспецифично же, только обычно используются чистые функции, не только без побочных эффектов.

fernandos ★★★
()

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

А вообще тут лучше аналогии приводить вот есть расчёты физики, если по общему состоянию мира и его данных ты ОДНОЗНАЧНО можешь вычислить какое будет следующее состояние мира то побочек нет.

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

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от fernandos

Побочный эффект — изменение среды выполнения.

Это очень расплывчато и мутно и мало что значит. Если побочка функции заключается в изменении глобальной переменной которая больше НИГДЕ не используется её просто в одностороннем порядке меняют и всё. То технически это побочный эффект по определению, а по факту нет.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Если побочка функции заключается в изменении глобальной переменной которая больше НИГДЕ не используется её просто в одностороннем порядке меняют и всё

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

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

вам в виде скриншота

Ох, я сейчас только понял что нарушил лицензию книги, т.к.:

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

Модератор, снесите скорее то сообщение

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

Мало ли что он там написал. Закон выше писюлек и хотелок автора. В данном случае это fair use.

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

Ох, я сейчас только понял что нарушил лицензию книги, т.к.:

Ты процитировал «в объеме, оправданном целью цитирования». так что всё нормально.

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

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

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

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

а вы создали экземпляр модержащий часть книги ? Что такое экземпляр ?

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

Будет, но оно ничего не изменит. x+y=z не имеет побочных эффектов ровно до той поры пока z не влияет на x или y или на то что их создаёт.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Будет, но оно ничего не изменит. x+y=z не имеет побочных эффектов ровно до той поры пока z не влияет на x или y или на то что их создаёт.

Ты прав, ничего не изменит. Побочный эффект как был, так и остался.

korvin_ ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

По тому определению да, по факту исполнения программы нет. Что важнее определение в вакууме или реальность?

Конечно реальность. Которая совпадает с определением:

glob var state = 0

func with_side_effect(delta) -> {
    state += delta
    return state
}

println(with_side_effect(1)) ; => 1
println(with_side_effect(1)) ; => 2

glob const value = 0

func without_side_effect(delta) -> {
    return value + delta
}

println(without_side_effect(1)) ; => 1
println(without_side_effect(1)) ; => 1

Прочти определение ссылочной прозрачности, если тебе тут непонятна разница.

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

Ну т.е. это практически любая строчка кода.

А это смотря как писать. Хороший стиль - это выносить максимально возможную долю логики в чистые функции (без побочных эффектов), а всю необходимую работу с execution environment делать локализованно. Короче, это в первую очередь про архитектуру.

P.S. А хороший язык форсирует такое разделение на уровне самого языка =)
Но среди мейнстримных ЯП так вроде никто не умеет, так что не особо релевантно

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

Ннененененененнененене. Я выше написал что (учитывая твой код) state есть, его меняют и всё. Более state нигде не используется, его просто меняют и всё =) Я до этого говорил про само краткое определение понятия, а не само понятие. Так у меня чаёк напрел. Поду папю, а потом вернусь и всех вас почитаю

=)

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

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

+1

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

Crocodoom ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Я выше написал что (учитывая твой код) state есть, его меняют и всё. Более state нигде не используется, его просто меняют и всё

Зачем же его меняют, если нигде не используют? Чтобы «жечь ватты зря»?

korvin_ ★★★★★
()
Последнее исправление: korvin_ (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

state есть, его меняют и всё. Более state нигде не используется

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

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

Кстати, черная дыра — чистая функция?

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

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

В обоих примерах побочный эффект </thread>

theNamelessOne ★★★★★
()

Жаль огорчать вас со Столяровым, но ваши read/write — это тоже побочные эффекты.

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