PDA

Просмотр полной версии : Макросы ОЛ: с побочными эффектами и/или детерминированные?



Владимир Ситников
20.04.2017, 10:28
В обсуждении Конечный автомат на ПР200 (http://www.owen.ru/forum/showthread.php?t=26579&page=3&p=244895&viewfull=1#post244895) тов anthrwpos выссказал мысль, что


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

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

Во-первых, Wikipedia:

Побочный эффект (https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B1%D0%BE%D1%87%D0%BD%D1%8B%D0%B9_% D1%8D%D1%84%D1%84%D0%B5%D0%BA%D1%82_(%D0%BF%D1%80% D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0 %BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)). Если вызвать функцию с побочным эффектом дважды с одним и тем же набором значений входных аргументов, может случиться так, что в качестве результата будут возвращены разные значения. Такие функции называются недетерминированными функциями с побочными эффектами.

В английской статье:

Side effects (https://en.wikipedia.org/wiki/Side_effect_(computer_science)). In the presence of side effects, a program's behaviour may depend on history; that is, the order of evaluation matters. Understanding and debugging a function with side effects requires knowledge about the context and its possible histories
Иными словами, тут тоже говорится, что "если есть побочные эффекты, то результат может зависеть от истории выполнений".

Апофеозом выступает такое сообщение:

блинк - обычная чистая функция.
И это при том, что чистая функция это

Чистота функции (https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D1%82%D0%BE%D1%82%D0%B0_%D1%84% D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8): 1. является детерминированной;
2. не обладает побочными эффектами.
Наличие только одного из свойств недостаточно, для того чтобы функция была чистой.
...
Недетерминированность функции — возможность возвращения функцией разных значений несмотря на то, что ей передаются на вход одинаковые значения входных аргументов. В этом случае невозможно построить однозначную таблицу значений функции


Очевидно, что blink возвращает разные значения, несмотря на то, что значения на входе не изменяются. Blink выдаёт то нолик, то единичку. Значение изменилось? Да. Агрументы запуска blink меняли? Нет. Всё -- это недетерминированность функции.
Значит ли это, что "blink ущербная функция"? Едва ли. Просто с точки зрения computer science, blink не является чистой функцией.


В конце концов, anthrwpos выдал такое заключение:

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

Я, конечно, соглашусь, что считать Wikipedia "основой основ" неправильно, но, если в Wikipedia написано "странное", то стоит перепроверить _свою_ позицию.
Вот откуда такая уверенность, что все авторы на Wikipedia ошиблись (и в русской и в английской версии статьи)?

Внимание, вопрос:

На этом, вопрос к тов. anthrwpos: приведите, пожалуйста, пример недетерминированной функции. Раз утверждаете, что ОЛ макрос это "детерминированная функция без побочных эффектов", и считаете, что "развертка по времени это тоже простой аргумент" то приведите пример недетерминированной функции.
Поясню к чему я веду: в подавляющем количестве случаев (почти во всех), выходное значение функции зависит от текущих аргументов и истории прошлых запусков.
Если следовать логике "история запусков это просто аргумент", то получается, что почти все функции являются "детерминированная функция без побочных эффектов".
Очевидно, что это ересь, но давайте посмотрим как у вас получится?

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

Ну или процитируйте хоть что-нибудь, говорящее о том, что "развертка во времени это аргумент".
Слова "есть единое пространство-время и относительность одновременности" в контексте "чистых функций" это, простите, бред сивой кобылы. Это реально так, ведь у слова "чистая функция" есть определение, и на него пространство-время не действует.
У ФБ SET_RESET_TRIGGER(S, R) сколько аргументов? Два или бесконечное количество? Ну вот реально как вы собрались вкрячивать "развертку времени" в качестве аргумента?


Более того, сама длительность выполнения программы это тоже побочный эффект (https://en.wikipedia.org/wiki/Side_effect_(computer_science)#Temporal_side_effec ts).
Приведу пример: в ОЛ длительность обычной функци fMUL наверняка зависит от входных аргументов (процессор ПР200 не умеет работать с плавающей точкой, и в Си библиотеке для этого процессора функция fMUL эмулируется). Поэтому, если совсем строго говорить, то ОЛ макрос уж точно с побочными эффектами.
Да, длительность выполнения важна в какой-нибудь безопасности, поэтому сейчас длительностью можно пренебречь. Но я привожу длительность тут для того, чтобы вы хоть как-то задумались над тем, что на самом деле в классической литературе по программированию принято называть словом "побочный эффект".


PS. Пункт 4.г правил я видел, но считаю, что тема интересна не только одному anthrwpos.

anthrwpos
20.04.2017, 13:04
Вообще говоря, чтобы предметно спорить по теории программирования, нам следует ссылаться на литературу по теории программирования.
Я к сожалению, компьютер сайенс курса не слышал, поэтому я такой литературы не знаю.
Мои сведения о чистых функциях я почерпнул из учебной литературы по языку Haskell.
И я не знаю, как у вас в Википедии, но у нас в Хаскеле действуют следующие определения:

Детерминированностью функции называется однозначное состояние выхода зависящее только от состояния входа и не зависящее от каких бы то ни было внешних состояний.

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

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

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

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

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

Владимир Ситников
20.04.2017, 14:03
Вообще говоря, чтобы предметно спорить по теории программирования, нам следует ссылаться на литературу по теории программирования.
Давайте, же, хоть куда-нибудь сошлитесь. Забавно выглядит, когда вы ругаете мои ссылки, а сами вообще никаких не приводите.

У ФБ SET_RESET_TRIGGER(S, R) сколько аргументов?
Это чистая функция в вашем понимании?

Можете сделать set_reset "чистую функцию" в Haskell понимании термина "pure function"?
Давайте же:

set_reset s r = ...


То что у вас написано в ссылке с русской википедии, так там перепутано понятие недетерминированности (разный выход при одинаковом входе) и побочный эффект. При чем здесь побочный эффект? Само выражение "побочный эффект" подразумевает, что источник побочного эффекта оказывает некое неявное, побочное влияние на что либо другое. Влияние чего-то там на результат работы функции было бы странно называть побочным эффектом функции, не так ли?)
1) Присмотритесь, и поймёте, что слова "Если вызвать функцию с побочным эффектом дважды" wikipedia не являются определением "недетерминированности", а они описывают пример того, что может произойти, если функция с побочным эффектом. В этом ключе, никакого перепутывания нет.
Там говорится, что, если функцию вызывали 2 раза и она вернула разное на одних и тех же данных, то такую функцию называют недетерминированной.
Да, бывают другие недетерминированные функци. Но, если так окажется, что вызвали с одними аргументами, а вернулось разное, то уж детерминированной эту функцию называть никак нельзя.
Опираясь на этот пример, я настаиваю на том, что set_reset_trigger (SR триггер в ОЛ) это недетерминированная функция с побочным эффектом (побочный эффект заключается в изменении скрытого состояние, которое можно наблюдать по результатам последующих вызовов этого SR триггера).

2) Странно или нет называть, но и в русской и в английской версии говорится, что "функция обладает побочным эффектом, если она взаимодействует с окружением".
"observable interaction with its calling functions or the outside world"

side effects (https://en.wikipedia.org/wiki/Side_effect_(computer_science)) For example, a particular function might modify a global variable or static variable, modify one of its arguments, raise an exception, write data to a display or file, read data, or call other side-effecting functions
3) Вот специальный пример из английской статьи:

side effects (https://en.wikipedia.org/wiki/Side_effect_(computer_science)) A function without side effects may be impure, for example if its output depends on the value of a global variable.



В английской версии написано "при побочных эффектах результат работы функции может зависеть от истории". Может зависеть, а может независеть... Я нахожу данное определение бессодержательным.
Оу, оу. SET_RESET_TRIGGER это чистая функция? Это функция без побочных эффектов?
По какому признаку?




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

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


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

Филоненко Владислав
20.04.2017, 14:43
Переводя с заумного на русский.
Правильно ли, что машина поворачивает ВСЕГДА налево, если налево крутится руль или допустимы варианты (но машина будет иметь в 2 раза более мощный двигатель)?

Владимир Ситников
20.04.2017, 14:50
Переводя с заумного на русский.
Правильно ли, что машина поворачивает ВСЕГДА налево, если налево крутится руль или допустимы варианты (но машина будет иметь в 2 раза более мощный двигатель)?

Зависит от.
Если бы машина была чистой функцией, то, да, она всегда поворачивала бы налево при вращении руля налево.

Но, по факту, может быть скрытое состояние ("сломалась рулевая"), и при повороте руля машина вообще не повернёт.
Или же, при движении по льду руль можно хоть обкрутиться, а машина не повернёт.

anthrwpos
20.04.2017, 20:47
Можете сделать set_reset "чистую функцию" в Haskell понимании термина "pure function"?
Давайте же:

set_reset s r = ...

Ну, просто ради развлечения)


set_reset :: Bool -> Bool -> State Bool ()
set_reset False False = state (\w -> ((),w))
set_reset True False = state (\_ -> ((),True))
set_reset _ True = state (\_ -> ((),False))

Здесь есть некоторое жульничество, но формально с точки зрения языка, вся эта конструкция является девственно чистой)
Я просто хочу посмотреть, что вы на это скажете ;)

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

Владимир Ситников
20.04.2017, 21:03
Ну, просто ради развлечения)
Пока я вспоминаю Haskell, ответьте, всё-таки на вопросы про то, сколько аргументов у ФБ SR-триггер, и является ли он детерминированной и/или чистой функцией.

anthrwpos
20.04.2017, 21:08
У SR два аргумента, он определенно не имеет побочных эффектов, а вот является ли он детерминированным, я еще не решил. Всё будет зависеть от того, смогу я убедить самого себя, что детерминированность в смысле развертки входов во времени считается или нет)
Если есть конкретные контраргументы против такого определения детерминированности, я с удовольствием их обсужу)

Владимир Ситников
20.04.2017, 21:27
У SR два аргумента, он определенно не имеет побочных эффектов, а вот является ли он детерминированным, я еще не решил. Всё будет зависеть от того, смогу я убедить самого себя, что детерминированность в смысле развертки входов во времени считается или нет)
Если есть конкретные контраргументы против такого определения детерминированности, я с удовольствием их обсужу)

Контраргументы простые и не менялись с самого моего первого сообщения.
Аргумента у SR два. Аргумента типа "развёртка входов во времени" у SR просто-напросто нет.

0) О какой "развёртке времени" вообще идёт речь, если у SR только два аргумента S и R?

1) Представим себе реальный блок SR.
Внимание, вопрос: что вернёт вызов SR(S=FALSE, R=FALSE). Что вернёт блок?
Может вернуть как TRUE, так и FALSE. Значит, это недетерминированная функция.

В этом плане, SR триггер ничем не отличается от "чтения файла" или "чтения координат мыши"

2) Теперь к "побочным эффектам".
У SR есть скрытое состояние. И вызовы с параметрами (S=TRUE, R=FALSE), (S=FASLE, R=TRUE) меняют это самое скрытое состояние SR триггера.
Изменение этого состояния можно наблюдать через вызов SR(S=FALSE, R=FALSE).
По определению, это и называется "функция с побочными эффектами".

Владимир Ситников
20.04.2017, 23:11
Ну, просто ради развлечения)


set_reset :: Bool -> Bool -> State Bool ()
set_reset False False = state (\w -> ((),w))
set_reset True False = state (\_ -> ((),True))
set_reset _ True = state (\_ -> ((),False))

Здесь есть некоторое жульничество, но формально с точки зрения языка, вся эта конструкция является девственно чистой)
Я просто хочу посмотреть, что вы на это скажете ;)

Делаю ставку на то, что тут вы пропихиваете дополнительный аргумент через pointfree.
На вопрос "сколько аргументов у SR-триггера" вы отвечаете два, но тут дополнительно подали аргумент "историю прошлых серий" он же "глобальное состояние".

Если объяснение неверное, то я попрошу вас дописать пример использования этого самого SR-триггера и всё встанет на свои места.




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

Ну, реально.

Поэтому, "изменение состояния" формулируется обычно как "наблюдаемое изменение состояние". Иными словами, если какое-то глобальное состояние изменяется, но это невозможно увидеть, то это "не считается". Именно поэтому я и называю ФБ SR-триггера блоком с побочным эффектом.

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

anthrwpos
21.04.2017, 05:20
Контраргументы простые и не менялись с самого моего первого сообщения.
Аргумента у SR два. Аргумента типа "развёртка входов во времени" у SR просто-напросто нет.
тогда предлагаю такой вариант:
у SR два аргумента: история состояний подаваемых на S и история состояний подаваемых на R. Выход - история выходных состояний. Почему нет ?

anthrwpos
21.04.2017, 05:37
Делаю ставку на то, что тут вы пропихиваете дополнительный аргумент через pointfree.
На вопрос "сколько аргументов у SR-триггера" вы отвечаете два, но тут дополнительно подали аргумент "историю прошлых серий" он же "глобальное состояние".
Если объяснение неверное, то я попрошу вас дописать пример использования этого самого SR-триггера и всё встанет на свои места.


Пример использования


module Hs where

import Control.Monad.State

set_reset :: Bool -> Bool -> State Bool ()
set_reset False False = state (\w -> ((),w))
set_reset True False = state (\_ -> ((),True))
set_reset _ True = state (\_ -> ((),False))

main :: IO ()
main = print $ execState prc False

prc :: State Bool ()
prc = do
set_reset True False
set_reset False False

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


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

capzap
21.04.2017, 06:57
как много хаскеля стало https://m.habrahabr.ru/post/327026/ оказывается

Владимир Ситников
21.04.2017, 09:41
Пример использования...
здесь в функции main вызывается функция execState, которой передается начальное состояние и которая возвращает конечное состояние.
execState получив начальное состояние запускает функцию prc, где мы производим различные вычисления с использованием SR-триггера путем вызова функции set_reset.
Вообще мы конечно можем там и любой другой код написать, где мы например, вычисляем с какими входами вызывать set_reset.
Т.е. всё, как я и говорил: вы здесь в функцию set_reset передаёте "состояние триггера".
Да, в вашем исполнении функция set_reset является чистой, но вы жульничаете в том плане, что помимо S и R аргументов передаёте дополнительный аргумент с состоянием триггера.

Иначе говоря: SR_triger(S, R, prevState) можно называть чистой функцией.

Но мы говорим про ОЛ. В ОЛ у SR-триггера всего два входа.
Ну и сами же говорили, что у SR-триггера ДВА аргумента.



Еще как возможно. На этом весь Хаскель и сделан.
В вышеприведенном примере мы используем монаду State, которая создает свое внутреннее локальное состояние. Её использование совершенно не нарушает чистоты языка.
В частности, вы можете прочитать это состояние из любой чистой функции и она останется чистой функцией, потому что читается локальное, внутреннее состояние. Но никакая чистая функция не может прочитать глобальное внешнее состояние создаваемое монадой IO.
Да да да.

По-вашему, любой ФБ является "чистым"?
По-вашему, любая программа из ФБ, не обращающаяся к файлам/IO является "чистой"?

Владимир Ситников
21.04.2017, 09:51
Собственно: да, для любой ОЛ программы/макроса можно составить Haskell программу, которая ведёт себя так же (ну, возвращает те же значения при тех же входах).
Работу с сетевыми переменными пока опустим. Даже работу с временем можно опустить (хотя я ни разу не соглашусь, что "ОЛ blink это читая функция")

Но значит ли это, что любая ОЛ программа является "чистой"? Вовсе нет. Или, по-вашему, действительно любая ОЛ программа является "чистой", "детерминированной" и "без побочных эффектов"?
Поэтому неправильно "оправдывать ОЛ" словами <<У макроса на вход помимо его реальных аргументов есть ещё "аргумент с состоянием", который передаётся неявно>>.

Да нет никакого дополнительного аргумента у ОЛ макроса.
Запускаешь ОЛ макрос 2 раза -- и он возвращает разное. По определению это означает, что макрос не является детерминированным. Какие ещё разговоры могут быть?

Владимир Ситников
21.04.2017, 10:17
Если пользоваться критерием "программу можно перевести на Haskell, а там все функции чистые, значит в исходной программе тоже всё <<чисто>>", то так можно дойти до того, что вообще все языки программирования основаны на чистых функциях. Разумеется, это бред, ведь Haskell Тьюринг-полный и на него можно перевести любую программу с любого другого языка.

Поэтому для определения "чистоты" нужно не просто говорить "ежу понятно, что в ОЛ макросы являются чистыми", а подтверждать это со ссылкой на определение.
И я не устану повторять, что никакого скрытого аргумента "Control.Monad.State" у ОЛ макроса нет. Есть только те аргументы, которые выведены на экран у самого макроса.

anthrwpos
21.04.2017, 12:40
Т.е. всё, как я и говорил: вы здесь в функцию set_reset передаёте "состояние триггера".
Таки нет!)
Посмотрите на сигнатуру set_reset. Она принимает только два Bool аргумента и никаких предыдущих состояний)
Состояние содержится внутри функции prc, которую мы вызываем посредством execState.

По-вашему, любая программа из ФБ, не обращающаяся к файлам/IO является "чистой"?
Почти так. Всё, что не имеет никаких средств для обращения к IO по видимому, является чистым.

Владимир Ситников
21.04.2017, 12:44
Почти так. Всё, что не имеет никаких средств для обращения к IO по видимому, является чистым.
О, круто (с вашего позволения, я пока не буду отвечать про сигнатуру set_reset)


Давайте посмотрим на такой код на C:



int counter = 0;

int abcd() {
counter = counter + 1;
return counter;
}


Внимание, вопрос: является ли функция abcd чистой?
Очевидно, что IO эта функция не выполняет.

anthrwpos
21.04.2017, 12:54
Собственно: да, для любой ОЛ программы/макроса можно составить Haskell программу, которая ведёт себя так же

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


Но значит ли это, что любая ОЛ программа является "чистой"?
Разумеется нет. ОЛ программа читает входы и записывает выходы.
Я продвигаю идею о чистоте только макросов.

anthrwpos
21.04.2017, 12:59
Давайте посмотрим на такой код на C:



int counter = 0;

int abcd() {
counter = counter + 1;
return counter;
}


Внимание, вопрос: является ли функция abcd чистой?
Очевидно, что IO эта функция не выполняет.
Нет, поскольку эта функция может читать ввод посредством некой другой функции, которая будет записывать его в переменную counter.

А в хаскеле вы из монады IO повлиять на состояние монады State не можете никак =)

Владимир Ситников
21.04.2017, 13:05
Нет, поскольку эта функция может читать ввод посредством некой другой функции, которая будет записывать его в переменную counter.
Чего чего?
"функция может читать ввод посредством некой другой функции" ?

О чём вообще речь. IO в программе вообще не происходит. Тут же просто сложение.
Скажите, пожалуйста, по какому принципу вы относите эту функцию abcd к нечистым?

Я могу добавить больше ограничений: никакая другая функция не обращается к переменной counter. Ни пишет, ни читает.
Что? abcd это чистая функция в таком случае?

Владимир Ситников
21.04.2017, 13:11
Ну сам по себе blink написать нельзя, ибо чистая программа не имеет доступа к системному времени и не может рассчитать время цикла. Но если время
цикла постулировать как константу, можно чистым образом и блинк сделать)
Что за бред? На Haskell нельзя написать blink?
Вы в своём уме? Data.Time.Clock и вперёд.
Становятся ли Haskell функции от этого нечистыми? Нет. Как-никак, в Haskell вообще все функции являются чистыми функциями.

Но вы, я так понял, считаете, что "нечистые" это только те функции, которые выполняют IO (ну, читают файлы, считывают значения DI/DO).
Да, те функции, которые читают файлы нечистые.
Но могут быть (разумеется, не в Haskell, а в Си, в ST, в ОЛ, в МЭК61131 и т.п.) нечистыми даже те функции (ФБ, макросы), которые с файлами и IO никогда вообще не работают.

anthrwpos
21.04.2017, 13:55
Чего чего?
"функция может читать ввод посредством некой другой функции" ?

О чём вообще речь. IO в программе вообще не происходит. Тут же просто сложение.
Скажите, пожалуйста, по какому принципу вы относите эту функцию abcd к нечистым?
Переменная которую использует эта функция глобальная. Её чтение равносильно чтению ввода, потому что к этой переменной имеет доступ любая функция в программе, в том числе и некая (предполагаемая) функция, которая может осуществлять ввод.
То что этого не происходит в вашей конкретной программе не делает эту функцию чистой)
Чистота функции - это свойство самой функции, оно не должно зависеть от того, как устроена ваша остальная программа.

Владимир Ситников
21.04.2017, 14:05
Чистота функции - это свойство самой функции, оно не должно зависеть от того, как устроена ваша остальная программа.

О, я тоже так думаю.

А такой код? Это чистая функция?
На всякий, случай: static объявляет такую переменную, которая сохраняет своё состояние между вызовами функции (http://wm-help.net/lib/b/book/1369887060/229)


int abcd2() {
static int counter; /* обращаем внимание на слово static */
counter = counter + 1;
return counter;
}


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

В коде abcd2 к переменной counter уж точно никогда не сможет обратиться ни одна другая функция.
Что? abcd2, получается, чистая функция?

Владимир Ситников
21.04.2017, 15:02
Т.е. всё, как я и говорил: вы здесь в функцию set_reset передаёте "состояние триггера".
Да, в вашем исполнении функция set_reset является чистой, но вы жульничаете в том плане, что помимо S и R аргументов передаёте дополнительный аргумент с состоянием триггера.


Тут я ошибся. Да, действительно показанная реализация set_reset удовлетворяет моему исходному вопросу, и получает всего 2 аргумента.
Да, был неправ, когда говорил про pointfree -- оно в конкретном случае не играет роли.

Да, ваша прошлая реализация set_reset не получает никаких лишних скрытых аргументов, но эта реализация и не возвращает bool результат.
Технически, ваша реализация set_reset возвращает функцию "состояние триггера должно сохраниться", "состояние триггера должно перейти в false", и т.п.
Потом эти функции последовательно применяются к начальному состоянию.

Да, это позволяет сделать как бы SR триггер на Haskell, но это вольная/творческая переработка ОЛ программы.

В том же самой же среде ОЛ, SR триггер получает два bool на вход и тут же возвращает bool на выходе.

Поэтому, переформулирую вопрос про SR-триггер.
Реализуйте вот такой SR-триггер:

set_reset :: Bool -> Bool -> Bool
set_reset s r = ...

SR-триггер в ОЛ это именно такой блок. Получает два bool, возвращает bool. Вы утверждаете, что он чистый, значит должно быть несложно составить аналогичную Haskell функцию.

anthrwpos
21.04.2017, 18:30
Да, ваша прошлая реализация set_reset не получает никаких лишних скрытых аргументов, но эта реализация и не возвращает bool результат.

Вот это правильно)


Поэтому, переформулирую вопрос про SR-триггер.
Реализуйте вот такой SR-триггер:

set_reset :: Bool -> Bool -> Bool
set_reset s r = ...

Вот такой триггер сделать невозможно.

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

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

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

Владимир Ситников
21.04.2017, 19:23
Вот такой триггер сделать невозможно.
Ну вы же сами только что сказали, что вот такой SR-триггер не является чистой функцией:


set_reset :: Bool -> Bool -> Bool
set_reset s r = ...

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

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


Никаких фундаментальных недостатков чистоты в смысле развертки во времени я пока не нашел.
Где ищите?
Хоть что-нибудь читаете?

Вот пример:


https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io
Here are the fundamental properties of a pure function:

1. A function returns exactly the same result every time it's called with the same set of arguments. In other words a function has no state, nor can it access any external state. Every time you call it, it behaves like a newborn baby with blank memory and no knowledge of the external world.
2. A function has no side effects. Calling a function once is the same as calling it twice and discarding the result of the first call. In fact if you discard the result of any function call, Haskell will spare itself the trouble and will never call the function. No wonder Haskell has a reputation for laziness (more about it later).

Смотрите внимательно на пункт №1. И читайте: "returns exactly the same result every time it's called with the same set of arguments".
Ваша set_reset функция при вызове set_reset False False реально возвращает одну и ту же функцию.
Тут "развёртка по времени" не играет никакой роли. Всё очень просто: вызвали set_reset False False -- получили в ответ одну и ту же функцию. Правда, полученная функция не имеет ничего общего с состоянием какого-либо SR триггера в ОЛ программе, но не суть.

Теперь же про ОЛ: там мы вызвали SR триггер с аргументами FALSE, FALSE. И что он нам вернёт? TRUE? FALSE? Да пёс его знает, ведь возвращённое значение зависит от того, чему равно состояние триггера перед вызовом.


Теперь про abcd2.
Функция abcd2 при двух вызовах с одними и теми же аргументами возвращает разные результаты. При этом, вообще неважно где именно она хранит состояние переменной counter. Хоть "внутри функции", хоть "в глобальной области", хоть в регистре процессора. Это неважно. Важно то, что вызвали два раза с одинаковыми аргументами, а она, собака, вернула разные значения. Всё, баста карапузики, эта функция "не является детерминированной", и, значит, она не может являться "чистой" функцией.
Если не нравится слово "не является детерминированной", то можно с тем же успехом процитировать статью: не выполнено свойство "A function returns exactly the same result..."

Именно из-за этого сами функции abcd и abcd2 не являются чистыми функциями.
Заметьте, я вообще не использовал при этом "вспомогательные гипотетические функции, которые могут читать-писать counter".
Мне достаточно того факта, что "вызвали функцию, она вернула разное, значит не чистая".

Владимир Ситников
21.04.2017, 19:33
Вот такой триггер сделать невозможно.
Ну и самый главный вывод: я хочу, чтобы вы признали свою ошибку в словах


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

Макрос легко отлаживается за счет его опять-же, "чистоты".

Согласитесь, что ошибались, когда называли "каждый ОЛ макрос" "чистой функцией, детерминированной функцией, без побочных эффектов"?


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




Если в макросе есть обратная связь или какой-нибудь функциональный блок (blink, sr-триггер), или write to FB, то этот макрос наверняка не является чистым.
Разумеется, можно blink просто-напросто не подключить к выходам. Но, если blink как-то влияет на выходы, то, всё, макрос 100% недетерминирован. Если в макросе SR триггер влияет на выход и связан со входами макроса, то это 100% макрос с побочным эффектом.

Да, чистые функции проще тестировать, но эта простота и возникает только для тех функций, которые не зависят от истории прошлых запусков.
Функция "add :: Int -> Int -> Int" это чистая функция. Её протестировать несложно.

А, если в макросе есть SR триггер, то тестировать такой макрос гораздо сложнее, т.к. нужно подавать разные истории входов, а этих историй потенциально очень большое количество. Историю какой длины нужно брать? 10 циклов? 100циклов? или, может 10000 циклов?
Макрос с SR триггером не является чистой функцией, и тестировать его действительно сложнее.

anthrwpos
21.04.2017, 20:15
Это неважно. Важно то, что вызвали два раза с одинаковыми аргументами, а она, собака, вернула разные значения.

Вы совершаете ошибку, заключая все такие функции в один ряд.
Функции, обладающие предложенной мной чистотой в смысле развертки во времени они конечно-же не являются чистыми в смысле мгновенной детерминированности, однако они наследуют все преимущества чистых функций.
Более того, я могу предложить чистую функцию следующего типа: sr_list :: [Bool] -> [Bool] -> [Bool], в которой последовательно идущие значения выходного списка меняются по правилам изменения состояния SR-триггера на основе значений входящих списков.
И вы не сможете предложить никаких аргументов, чем функциональный блок SR в ОЛ хуже, чем данная функция за исключением того, что развертка во времени заменяется разверткой в памяти.
Поэтому я настаиваю по меньшей мере не ставить такие функции в один ряд с методами ООП или функциями из Си, а сам я считаю их столь-же чистыми, пока не найду логичное обоснование того, почему так считать нельзя.

anthrwpos
21.04.2017, 20:25
Сейчас получается, что никакой источник привести не можете, и одновременно с этим настаиваете на своей правоте. Так не бывает.
Я не настаиваю на своей правоте. Я предполагаю, что моя идея разумна и лишь защищаю это предположение) Аксиоматические обоснования того, что это нечистая функция потому что это не называют чистой функцией меня не устраивают. Мне для того, чтобы убедить себя в обратном, нужны аргументы, почему плохая идея называть это чистой функцией.

Да, чистые функции проще тестировать, но эта простота и возникает только для тех функций, которые не зависят от истории прошлых запусков.
Функция "add :: Int -> Int -> Int" это чистая функция. Её протестировать несложно.

функцию add_list :: [Int] -> [Int] -> [Int] тестировать ничем не сложнее, чем нечто, имеющее тип Int -> Int -> Int, в котором поведение зависит от истории запусков.
Преимущество чистоты вовсе не в том, что сокращается пространство возможных состояний, а в том, что поведение чистой функции становится предсказуемым и не изменяется при использовании её в различных внешних условиях.
Так то чистые функции могут иметь принципиально ничем не ограниченное множество возможных состояний с сколь угодно сложной структурой.

rovki
21.04.2017, 20:28
Во понесло... -два гения на форуме это хорошо:D Может простых смертных в покое оставят :D

Владимир Ситников
21.04.2017, 20:36
предложенной мной чистотой

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


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

Давайте хоть какую-нибудь ссылку -- можно будет предметно обсуждать.
Я приводил Wikipedia (русские и английские статьи) -- вы говорите, что автор статей ничего не понимает.
Я приводил ссылку на https://www.schoolofhaskell.com -- вы игнорируете.

Вот вам ссылка на stackoverflow:

http://stackoverflow.com/a/4382247/1261287
In a pure functional language, you can't do anything that has a side effect.

A side effect would mean that evaluating an expression changes some internal state that would later cause evaluating the same expression to have a different result. In a pure functional language you can evaluate the same expression as often as you want with the same arguments, and it would always return the same value, because there is no state to change.

For example, a pure functional language cannot have an assignment operator

Вот вам ссылка на haskell.org:

https://wiki.haskell.org/Functional_programming#Side_effects_through_monads
3.2.4.2 Side effects through monads
Another way of introducing side effects to a pure language is to simulate them using monads...

То, что в обычных языках называется "побочным эффектом" можно сэмулировать монадой.
Я утверждал, что SR триггер в смысле ОЛ обладает побочным эффектом, и как раз вы использовали монаду. Совпадение? Не думаю!

Ещё из haskell.org:

https://wiki.haskell.org/Functional_programming#Purity3.2 Purity
Some functional languages allow expressions to yield actions in addition to return values. These actions are called side effects to emphasize that the return value is the most important outcome of a function (as opposed to the case in imperative programming)
Иными словами, в чистых функциях запрещено выполнять какие-то дополнительные действия (yield actions) кроме как возвращать значение. Как раз таким "дополнительным действием" и является увеличение переменной counter в функциях abcd/abcd2. Как раз таким действием и является изменение состояния триггера в ОЛ.


Я к чему: море ссылок подтверждают мою позицию. Обратите внимание: они подтверждают не моё определение, а мою позицию. Вы же машете своим собственным определением (которое отличается от общепринятых) и смешиваете его с общепринятыми.



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

Если вы изобрели геометрию Лобачевского (ну, прямо своё понимание чистых функций) -- не вопрос. Но не надо тогда примазываться к словам "раз функция чистая, то её проще тестировать".
Согласно вашему определению "чистоты" подавляющее большинство функций являются чистыми, и такое определение теряет пользу.

anthrwpos
21.04.2017, 20:37
Да уж точно. Хотел за вчера-сегодня еще один макрос довести до ума и описание написать, а вместо этого обсуждаю чистые функции...:confused:

Владимир Ситников
21.04.2017, 20:41
Мне для того, чтобы убедить себя в обратном, нужны аргументы, почему плохая идея называть это чистой функцией
Вот представьте, если я любую функцию в названии которой нет буквы Ы буду называть чистой.
И попробуйте меня аргументированно убедить в том, почему это плохая идея.

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

Это называется "слышал звон, да не знаешь, где он".

Это не я должен убеждать вас в том, что "вы сами себе придумали плохое определение".
А это вы должны аргументировать почему ваше определение совпадает с общепринятым.

Владимир Ситников
21.04.2017, 20:43
Да уж точно. Хотел за вчера-сегодня еще один макрос довести до ума и описание написать, а вместо этого обсуждаю чистые функции...:confused:

Макросы это хорошее дело.
Хоть кто-то сделал экспоненциальное сглаживание для ПР (я эти ОЛ квадратики терпеть не могу).

Но вот говорить, что "все ОЛ макросы чистые" -- вовсе неправильно.

anthrwpos
21.04.2017, 21:09
Вот представьте, если я любую функцию в названии которой нет буквы Ы буду называть чистой.
И попробуйте меня аргументированно убедить в том, почему это плохая идея.


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

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

Владимир Ситников
21.04.2017, 21:29
У вас понятие чистой функции аксиоматическое. Вот это назвали чистой функцией и баста, значит так оно и есть. Вас вероятно не интересует, для чего вообще выделять какой-то класс функций в отдельную категорию, какие существуют преимущества и недостатки таких функций, как можно расширить или сузить данное определение, чтобы преследовать какую либо практическую цель.
У меня понятие одновременно и аксиоматическое и практическое.

Аксиоматику посмотрите в ссылках выше.

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

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

Вот реальный пример:

https://ru.wikipedia.org/wiki/Therac-25

Машина была сразу же выведена из эксплуатации и Хагер начал собственное расследование. Медсестра вспомнила, что в тот день она заменяла «x» на «e». Выяснилось, что если сделать это достаточно быстро, переоблучение случалось практически со 100-процентной вероятностью.
Это как раз пример того, что функцию, которая зависит не только от входных параметров, но ещё и от истории запусков проверять гораздо сложнее.
И эту ошибку нашли ценой гибели реальных пациентов.

Владимир Ситников
21.04.2017, 21:48
У вас понятие чистой функции аксиоматическое. Вот это назвали чистой функцией и баста, значит так оно и есть. Вас вероятно не интересует, для чего вообще выделять какой-то класс функций в отдельную категорию, какие существуют преимущества и недостатки таких функций, как можно расширить или сузить данное определение, чтобы преследовать какую либо практическую цель.

Исследуйте что хотите, но не пишите ересь типа такой:

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

При поиске в Google/Яндекс находятся вполне конкретные определения для слов "детерминированная функция" и "побочный эффект".
И эти определения никак не связаны с вашим определением. В ваш класс "чистых функций" входит гораздо больше функций, чем обычно принято.

Поэтому исследуйте что хотите и как хотите. Можно отдельную тему создать про это.

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

Это по меньшей мере странно, а в обычном понимании это полный бред.


Вот вам пример: anthrwpos -- дурак.
А, если вы скажете, что "ей -- смотрите, Владимир ругает и оскорбляет", то я скажу, что слово "дурак" тут означает "человек, разбирающийся в haskell state monad".
Хорошо так? По-моему, нехорошо.

Поэтому мне и не нравится, когда вы жонглируете словами, вкладывая в них свой смысл, который ну никак невозможно найти в Google.

Сергей0308
21.04.2017, 22:19
Извиняюсь, тут наверно нужно приоритеты расставить, список составить очерёдности кого ругать, что-то овен ругать желающих кот наплакал, вот посмотрите, тоже по своему всё называют:
http://www.owen.ru/forum/showthread.php?t=24760&highlight=%CE%E1%F9%E8%E5+%E2%EE%EF%F0%EE%F1%FB

Владимир Ситников
21.04.2017, 22:26
Извиняюсь, тут наверно нужно приоритеты расставить, список составить очерёдности кого ругать, что-то овен ругать желающих кот наплакал, вот посмотрите, тоже по своему всё называют:
http://www.owen.ru/forum/showthread.php?t=24760&highlight=%CE%E1%F9%E8%E5+%E2%EE%EF%F0%EE%F1%FB

Это всё разные вопросы.
Когда я предложил разработчикам ОВЕН называть "обратную связь" "линией задержки", то они пошли навстречу и в ОЛ 1.9 внесли такое изменение.

Разумеется, часть решений принята уже настолько давно, что, если сейчас что-то переименовать (например, INT в UNIT), то все начнут путаться.
Да, ОВЕН обновляется небыстро, но они хоть как-то реагируют.


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

Сергей0308
21.04.2017, 22:37
Так может не надо так наседать, высказали мнения и каждый остался при своём, так нельзя?

Владимир Ситников
21.04.2017, 23:11
Так может не надо так наседать, высказали мнения и каждый остался при своём, так нельзя?

Так нельзя, ведь:
1) anthrwpos использует свои домыслы, основывает на них ложные утверждения (http://www.owen.ru/forum/showthread.php?t=23754&page=37&p=245221#post245221), и тем самым уводит в сторону тему про p-code блок в ОЛ. Я специально не хочу в той теме обсуждать "чистоту p-code блока" или "чистоту ОЛ макроса", ведь понимаю, что это уведёт тему вообще в дебри хрен знает чего, и тогда p-code блока уж точно не видать.
Т.е. от лженауки anthrwpos налицо прямой вред теме про p-code блок. Тема и так непростая, так ещё и её постоянно по ложным следам разные личности уводят.

2) anthrwpos учит других плохому (http://www.owen.ru/forum/showthread.php?t=26579&page=3&p=244895#post244895). При этом эти самые другие делают неправильные выводы (http://www.owen.ru/forum/showthread.php?t=26579&page=3&p=244923&viewfull=1#post244923), основываясь на словах anthrwpos.
Поэтому, лучше научить anthrwpos тому, что на самом деле называется "детерминированной функцией" и что на самом деле является "побочным эффектом", чем постоянно расхлёбывать лженауку.


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

anthrwpos
22.04.2017, 05:36
Вот вам пример: anthrwpos -- дурак.
А, если вы скажете, что "ей -- смотрите, Владимир ругает и оскорбляет", то я скажу, что слово "дурак" тут означает "человек, разбирающийся в haskell state monad".
Хорошо так? По-моему, нехорошо.

Поэтому мне и не нравится, когда вы жонглируете словами, вкладывая в них свой смысл, который ну никак невозможно найти в Google.
Этот прием называется "доведение до абсурда".
Я предлагаю не произвольное изменение общепринятого определения на нечто с ним никак не связанное, а лишь некоторое его расширение.


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

Еще раз повторю.
"нечистую" функцию add2 :: Int -> Int -> Int, которая зависит от истории запусков тестировать ровно настолько-же сложно, как чистую функцию add_list :: [Int] -> [Int] -> [Int].
Поэтому концептуально ваш пример не может показать никаких недостатков моего понятия чистоты.



Поэтому, лучше научить anthrwpos тому, что на самом деле называется "детерминированной функцией" и что на самом деле является "побочным эффектом"
Если вы действительно хотите добиться этой цели, то вам придется принять мои условия, то есть обсуждать не аксиоматику, а концепцию :cool:
Я согласен отказаться от этой идеи, если будет концептуально показано, чем развертка во времени хуже развертки в список.

Владимир Ситников
22.04.2017, 10:44
Я предлагаю не произвольное изменение общепринятого определения на нечто с ним никак не связанное, а лишь некоторое его расширение.
Это и есть чистосердечное признание.
Вы намеренно искажаете смысл общепринятого определения. Понимаете, что искажаете и с упорством барана настаиваете на своём, изменённом варианте.

Согласитесь, наконец, то ошибались, поправьте или удалите свой комментарий в теме про p-code и потом уже можно обсуждать "какая чистота функции более концептуальна".