Автор Тема: Выход из цикла или смерть Кощея  (Прочитано 93863 раз)

ddn

  • Jr. Member
  • **
  • Сообщений: 59
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #135 : Январь 17, 2013, 06:02:13 am »
Функция без побочных эффектов (она же "чистая") - это функция, которая для одних и тех же аргументов всегда возвращает один и тот же результат и сама не вызывает функций с побочными эффектами.
Непонятно, зачем только эта рекурсивная добавка в определении.
Такая функция будет вносить (вообще говоря) побочные эффекты в выражения в которых она вызывается.

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

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

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

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

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


Кроме того, что функция может быть чистой и грязной (с побочными эффектами), она ещё может быть тотальной (гарантированно успешно завершится) и не тотальной (может выдать ошибку или никогда не завершиться).
Например, f(x)=5/x может выдать деление на ноль, и хоть она и является чистой, тотальной она не является.
Выход из функции по ошибке не является побочным эффектом, т.к. находится вне среды исполнения программы, т.е. вне видимости языка.


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

1. Я не считаю конкретно это изменение ПОБОЧНЫМ эффектом - хотя конечно это изменяет глобальное окружение
2. Вы черезчур сильно обобщаете свои рассуждения - следуя этому пути можно всегда предположить, что в одной из этих процедур есть и традиционный побочный эффект (прямое изменение значения глобальной  переменной не передающейся через интерфейс подпрограммы).. а раз так то и задача не имеет смысла...
1. А я считаю, по этой же причине. Такая "функция" является тривиально чистой, она тождественная, потому что "результат" здесь это само ссылочное значение "заяц" (а не "заяц^") равное ссылочному аргументу "заяц" (если конечно "функция" не меняет его значение).
2. Изменение значения глобальной переменной даже передающейся через интерфейс подпрограммы (как параметр-переменная) тоже является побочным эффектом. У функции без побочного эффекта не должно быть VAR/OUT-параметров.
Почему задача не имеет смысла? Не обязательно использовать функции. Требования использовать функции без побочного эффекта тоже нет в условии задачи. Только минимизация числа извлечений и сохранение промежуточных результатов.


Любое изменение глобального окружения функции внутри неё является побочным эффектом, будь-то ввод/вывод, прямое или косвенное изменение глобальной переменной.
Если функция хоть как-то влияет на изменение глобального (по отношению к ней) состояния программы, то эта функция имеет побочный эффект.
Если так рассуждать - то Хаскели и проч. "чистые" ФЯВУ  - не только таковыми не являются - но потенциально гораздо более опасны чем императивные ЯП.
"Чистые" ФЯВУ по сути это одни выражения, и никаких операторов.
Если мы хотим изменить "глобальное окружение" в "чистом" ФЯВУ (например, записать в лог), мы должны влючить значение этого "глобального окружения" в параметр функции, а затем вывести новое значение этого "глобального окружения" как компоненту результата.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #136 : Январь 17, 2013, 06:06:50 am »
Не знаю, говори ли кто или нет в этой ветке, неохота искать.
Я так понимаю, что Пётр озаботился такой ситуацией.
В теле цикле может быть несколько точек, где условие цикла может стать ложным.  Например, имея while (A and B and C),  в определённых точках тела цикла, там где фиксируются окончательно значения условий A, B,C. Если одно из этих условий  становится ложным, то остальное в теле цикла как бы уже можно и не исполнять.  Вот и появился соблазн синтаксически это дело оформить, размазав условие while по телу цикла.

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #137 : Январь 17, 2013, 06:16:22 am »
Да ладно Вам, у каждого свои тараканы, одному нужны инварианты, другой носится с циклом Дейкстры, третьему нужна выразительность, четвертому "только хардкор", пятому эффективное решение, ...
Так что и этот вариант ничуть не более извращенный, чем другие.
Тараканы мне не интересуют, у меня критерий только один - работает инструмент или нет. Поэтому я всегда прошу приводить примеры.

В вашем варианте нет разницы игла == null или нет. Делаем выводы об успешности...

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

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #138 : Январь 17, 2013, 06:18:36 am »
Не знаю, говори ли кто или нет в этой ветке, неохота искать.
Я так понимаю, что Пётр озаботился такой ситуацией.
В теле цикле может быть несколько точек, где условие цикла может стать ложным.  Например, имея while (A and B and C),  в определённых точках тела цикла, там где фиксируются окончательно значения условий A, B,C. Если одно из этих условий  становится ложным, то остальное в теле цикла как бы уже можно и не исполнять.  Вот и появился соблазн синтаксически это дело оформить, размазав условие while по телу цикла.
Ровно об этом я и сказал здесь http://oberspace.dyndns.org/index.php/topic,425.msg13272.html#msg13272

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

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #139 : Январь 17, 2013, 06:25:42 am »
Не знаю, говори ли кто или нет в этой ветке, неохота искать.
Я так понимаю, что Пётр озаботился такой ситуацией.
В теле цикле может быть несколько точек, где условие цикла может стать ложным.  Например, имея while (A and B and C),  в определённых точках тела цикла, там где фиксируются окончательно значения условий A, B,C. Если одно из этих условий  становится ложным, то остальное в теле цикла как бы уже можно и не исполнять.  Вот и появился соблазн синтаксически это дело оформить, размазав условие while по телу цикла.
Ровно об этом я и сказал здесь http://oberspace.dyndns.org/index.php/topic,425.msg13272.html#msg13272

Пожалуй, я сделал ошибку в том, что закопал самый главный пост внутри темы.
Ну, как я уже говорил, эта проблема в функциональщине решается монадами. Та же maybe например. То есть там этой проблемы нет в принципе.
Y = λf.(λx.f (x x)) (λx.f (x x))

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #140 : Январь 17, 2013, 06:30:39 am »
Там ровно та же проблема, цепочка в maybe не делает exit из себя, а выполняется целиком.

trurl

  • Full Member
  • ***
  • Сообщений: 133
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #141 : Январь 17, 2013, 06:34:54 am »
Автор при этом думал "как бы мне извратиться?"
А мне кажется, автор думал "как бы обеспечить правильное постусловие?" ;)

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #142 : Январь 17, 2013, 06:41:24 am »
Он таких слов не знает.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #143 : Январь 17, 2013, 06:48:28 am »
Там ровно та же проблема, цепочка в maybe не делает exit из себя, а выполняется целиком.
Вычисление цепочки выражений в монаде Maybe обрывается сразу же, как только одно из выражений в этой цепочке оказывается неуспешным.
Целиком же она выполняется только, если все выражения в ней вычислены успешно.
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #144 : Январь 17, 2013, 06:57:11 am »
В вашем варианте нет разницы игла == null или нет. Делаем выводы об успешности...
а, ну да, ilovb вынес эту проверку из цикла. но это ж не проблема - вернуть её на место, как в исходном вашем варианте - а нефиг было картинки вставлять вместо текста. Видимо Пётр такую диверсию сделал чтобы никто не смог скопипастить )

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #145 : Январь 17, 2013, 07:13:24 am »
Там ровно та же проблема, цепочка в maybe не делает exit из себя, а выполняется целиком.
Вычисление цепочки выражений в монаде Maybe обрывается сразу же, как только одно из выражений в этой цепочке оказывается неуспешным.
Это вам только так кажется. А на самом деле до конца цепочки идет проверка на Nothing.

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #146 : Январь 17, 2013, 07:26:24 am »
Автор при этом думал "как бы мне извратиться?"
А мне кажется, автор думал "как бы обеспечить правильное постусловие?" ;)
Видимо, trurl под автором имел в виду себя, а не ilovb, как я.
Ну тогда приведите инвариант вашего цикла.
Как никак, он входит в правильное постусловие.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #147 : Январь 17, 2013, 07:35:13 am »
Там ровно та же проблема, цепочка в maybe не делает exit из себя, а выполняется целиком.
Нет, целиком не выполняется. Как раз делается проверка между звеньями цепочки.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #148 : Январь 17, 2013, 07:42:45 am »
Там ровно та же проблема, цепочка в maybe не делает exit из себя, а выполняется целиком.
Вычисление цепочки выражений в монаде Maybe обрывается сразу же, как только одно из выражений в этой цепочке оказывается неуспешным.
Это вам только так кажется. А на самом деле до конца цепочки идет проверка на Nothing.
Кто Вам такое сказал? о_О
data  Maybe a  =  Nothing | Just a
  deriving (Eq, Ord, Generic)

instance  Monad Maybe  where
    (Just x) >>= k      = k x
    Nothing  >>= _      = Nothing

    (Just _) >>  k      = k
    Nothing  >>  _      = Nothing

    return              = Just
    fail _              = Nothing

Как видно, как только результатом очередного выражения в цепочке Maybe окажется Nothing, всё выражение обрывается и возвращается Nothing -- никакого продолжения вычислений в стратегии монады Maybe не предусмотрено.
Вы явно путаете с чем-то другим, возможно с монадой IO...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Выход из цикла или смерть Кощея
« Ответ #149 : Январь 17, 2013, 07:57:52 am »
Кто Вам такое сказал? о_О
Мне такое сказали авторы книги Real World Haskell http://book.realworldhaskell.org/read/monads.html
Цитировать
Note, though, that the chain is not completely short-circuited. Each (>>=) or (>>) in the chain will still match a Nothing on its left, and produce a Nothing on its right, all the way to the end. It's easy to forget this point: when a computation in the chain fails, the subsequent production, chaining, and consumption of Nothing values is cheap at runtime, but it's not free.
И обманули, гады  >:(