Re[113]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 11:58
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, samius, Вы писали:


S>>>>это IO, но это не функция.

S>>Формально — нет. Что такое функция? Грубо — соответствие между элементами двух множеств. Здесь мы имеем ровно один элемент, который не соответствует ничему.

ARK>Функция из unit в unit?

Элементы какого множества в какое она отображает?

S>>И я putStr считаю чистой. И тоже не назову других способов. Так что не так с кэшированием?


ARK>Тогда эти функции эквивалентны в разрезе кеширования.

Нет.

ARK>>>То же самое можно сделать с printf.

S>>Никто не утверждал обратного. Можно завернуть printf с параметрами в лямбду и кэшировать. Но это не делает саму printf чистой, разумеется. Обертка может быть чиста.

ARK>Не вижу отличий между кешированием завернутой в лямбду printf и вызовом putStr. Оно есть? Если нет, то получается, что кеширование не может быть признаком чистоты?

Признаком чистоты чего именно? Функция, возвращающая лямбду с завернутой printf — будет чиста как и putStr. Но сам printf от этого чище не стал.
Re[109]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 12:01
Оценка:
Здравствуйте, artelk, Вы писали:

A>Если учесть то, что "мы-то знаем" и переопределить "грязность" функции как ее возможность иметь побочные эффекты в виде транформации Мира либо если результат ее вычисления зависит от состояния Мира, то в Хаскелях будет возможно такое определение:

A>1. Функция НЕ является "грязной", если она не возвращает IO
A>Все остальные функции потенциально "грязные".

Но мы же знаем, что есть unsafe, позволяющий не возвращать IO, но плодить при этом грязь с чистым видом.
Re[110]: Мнение: объектно-ориентированное программирование —
От: artelk  
Дата: 13.11.19 12:07
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, artelk, Вы писали:


A>>Если учесть то, что "мы-то знаем" и переопределить "грязность" функции как ее возможность иметь побочные эффекты в виде транформации Мира либо если результат ее вычисления зависит от состояния Мира, то в Хаскелях будет возможно такое определение:

A>>1. Функция НЕ является "грязной", если она не возвращает IO
A>>Все остальные функции потенциально "грязные".

S>Но мы же знаем, что есть unsafe, позволяющий не возвращать IO, но плодить при этом грязь с чистым видом.

Ок,
1. Функция НЕ является "грязной", если она не возвращает IO и не делает unsafe штук
Все остальные функции потенциально "грязные".
Re[106]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 12:13
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, samius, Вы писали:


ARK>>>Ну, разработчики D как минимум не используют определение чистоты из википедии.

ARK>>>На мой взгляд, тот подход, который у них, вполне соответствует моему пониманию чистоты. Впрочем, я не настаиваю, это для меня не очень важно. Важнее отказ от википедийного определения.
S>>Уверен?

ARK>Угу: https://dlang.org/spec/function.html#pure-functions


ARK>

ARK>As a concession to practicality, a pure function can also:

ARK> read and write the floating point exception flags
ARK> read and write the floating point mode flags, as long as those flags are restored to their initial state upon function entry
ARK> perform impure operations in statements that are in a ConditionalStatement controlled by a DebugCondition.


ИИИ?

S>>Прости, конечно, но разве в D исключены эффекты окружения, введенные вычислителем?


ARK>D не полагается на вычислитель при определении чистоты. В D функция чиста, если имеет модификатор "pure".

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

S>>Смысл проверять чистоту DrawPoint, если она меняет canvas? И если возвращает новый, оставляя старый нетронутым по декларации, то тоже какой смысл?


ARK>Я не про чистоту DrawPoint, а в общем — про контракты функций. Чистота — один частный случай. Вопрос был — ты что, проверяешь вообще всё, все аргументы и все эффекты всех функций? Если нет, то почему тебе недостаточно просто сигнатуры и/или документации для того, чтобы рассуждать о чистоте функции?

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

S>>Ну или окружение. Тут синус, понимаешь, вычисляется, а здесь кофе пролили на клаву. Мухи налетели.


ARK>Да, или окружение. Еще раз вернусь в изначальное русло: я использую виртуальную машину для демонстрации того, что определение чистоты из википедии при написании кода является не слишком полезным, поскольку оно опирается на такие признаки, которые могут быть подделаны.

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


ARK>>>Ты пока не продемонстрировал этого отделения. То, что ты продемонстрировал, может быть повторено на любом грязном императивном языке.

S>>Так я и не утверждал, то хаскель делает что-то, что нельзя повторить на любом грязном и императивном языке. Я даже демонстрировал, как putStr мог бы выглядеть на C#.

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


Вызов хаскельной putStr возвращает не обертку, а IO. Но да, можно назвать ее оберткой. Это как C++ возвращал бы function, C# Action и т.п. Но вызов этой обертки не приводит к вызову putStr снова, т.к. putStr уже отработала, вернув обертку.
Когда ты оборачиваешь printf, то ты возвращаешь обертку, которая при вызове передаст управление в printf, как IO передаст управление в грязный экшн. Функции putStr и printf при этом на разных этажах находятся.
Re[109]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 12:18
Оценка:
Здравствуйте, samius, Вы писали:

S>С этим я не согласен, т.к. пункт 1 делает id грязным.

S>Удовлетворяет, т.к. принимает IO. Но она чистая. Привести пример на хаскеле о том, что id принимает IO?

Не уверен, что в определении Sinclair речь идет только о хаскеле. Оно общего вида. Если функция помечена соответствующим образом — она грязная (или, наоборот, чистая).

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

Насчет трактовки Sinclair можем у него самого спросить. Ау, Sinclair!

S>А вот, кстати, putStr этому определению не удовлетворяет, т.к. 1) не принимает IO. 2) не вызывает грязные функции. Следовательно, мне непонятно, почему ты называешь ее грязной даже по своему определению.


Да, тут ошибка. Под "принимает IO" имеется в виду "имеет метку IO", что для хаскеля является эквивалентом _возврата_ IO.
А для какого-нибудь Clean "меткой IO" является уникальный тип "World", причем и на входе, и на выходе.
В общем да, со словом "принимает" тут не вполне корректное определение.

S>Никакой обертки я не создавал. Я взял значение типа IO() и дал ему имя.


А есть ли — в разрезе кеширования — отличие от обертки у этого подхода?

S>Но это не есть закэшировал. Это именно что обертка. Аналог хаскеля был бы таким

S>
S>Action putStrLn1 = () => Console.WriteLine("query");
S>


Так это то же самое же.

ARK>>UPD. Я понимаю, что это немного другое. Но суть та же — результатом "кеширования" putStr является отложенное действие.

S>Но у тебя оно именно что не отложенное.

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

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

ARK>>Мой критерий НЕ зависит от окружения. Вообще. Даже если совсем НЕТ никакого окружения, даже если нет ни компилятора, ни даже компьютера — мой критерий дает четкое определение, чиста функция или нет.
S>да, четкое. Пример — id.

id, согласно моему критерию (а не твоей трактовке моего критерия), является чистой. У нее нет синтаксической метки грязи и в документации не сказано, что она делает грязь.

ARK>>Мне нравится такое определение, которое не требует внешних зависимостей от окружения.

S>А разве определение в википедии требует? Разве оно как-то намекает на то, что оператор сложения стал грязным от того, что грязное окружение фиксирует изменения регистров процессора? Или что если консоль перенаправили в dev/null, то это сделало любой консольный вывод чистым?

Там об этом не сказано. Тогда что же такое "ввод-вывод" и "побочные эффекты"? Получается, это не то, что мы можем увидеть глазами или пощупать руками, ведь окружение может влиять на это. Тогда что это такое? Это дергание определенных функций операционной системы (или окружения в широком смысле)? Так?
Re[111]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 12:22
Оценка:
Здравствуйте, artelk, Вы писали:

A>Здравствуйте, samius, Вы писали:


A>>>то в Хаскелях будет возможно такое определение:


S>>Но мы же знаем, что есть unsafe, позволяющий не возвращать IO, но плодить при этом грязь с чистым видом.

A>Ок,
A>1. Функция НЕ является "грязной", если она не возвращает IO и не делает unsafe штук
A>Все остальные функции потенциально "грязные".

Хорошо, но еще пусть это будет не определением (definition), а неким критерием, сформулированным для хаскеля на основе классического определения чистоты с учетом системы типов и бэкдоров хаскеля.
Re[114]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 12:27
Оценка:
Здравствуйте, samius, Вы писали:

S>>>>>это IO, но это не функция.

S>>>Формально — нет. Что такое функция? Грубо — соответствие между элементами двух множеств. Здесь мы имеем ровно один элемент, который не соответствует ничему.
ARK>>Функция из unit в unit?
S>Элементы какого множества в какое она отображает?

Пустого в пустое.

ARK>>>>То же самое можно сделать с printf.

S>>>Никто не утверждал обратного. Можно завернуть printf с параметрами в лямбду и кэшировать. Но это не делает саму printf чистой, разумеется. Обертка может быть чиста.
ARK>>Не вижу отличий между кешированием завернутой в лямбду printf и вызовом putStr. Оно есть? Если нет, то получается, что кеширование не может быть признаком чистоты?
S>Признаком чистоты чего именно? Функция, возвращающая лямбду с завернутой printf — будет чиста как и putStr. Но сам printf от этого чище не стал.

ОК. Тут согласен. Эквилибристика хаскеля заключается в том, что обертка создается "внутри", но формально прямого аналога в С нет. Однако можно считать, что printf возвращает обертку, но не с захваченными аргументами, как у хаскеля, а со всеми теми же. Глупый трюк, зато так можно тоже считать printf чистой.
Re[110]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 12:41
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, samius, Вы писали:


S>>Удовлетворяет, т.к. принимает IO. Но она чистая. Привести пример на хаскеле о том, что id принимает IO?


ARK>Не уверен, что в определении Sinclair речь идет только о хаскеле. Оно общего вида. Если функция помечена соответствующим образом — она грязная (или, наоборот, чистая).


Не уверен, что можно сформулировать "принимает IO" в общем виде. printf никакого IO не принимает и ничем не помечен.

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

Здрасте. А что мне в id мешает засунуть unsafe? Одной сигнатуры недостаточно.

S>>А вот, кстати, putStr этому определению не удовлетворяет, т.к. 1) не принимает IO. 2) не вызывает грязные функции. Следовательно, мне непонятно, почему ты называешь ее грязной даже по своему определению.


ARK>Да, тут ошибка. Под "принимает IO" имеется в виду "имеет метку IO", что для хаскеля является эквивалентом _возврата_ IO.

ARK>А для какого-нибудь Clean "меткой IO" является уникальный тип "World", причем и на входе, и на выходе.
ARK>В общем да, со словом "принимает" тут не вполне корректное определение.
Но это не определение, это лишь метка. Не метка делает функцию чистой или грязной.

S>>Никакой обертки я не создавал. Я взял значение типа IO() и дал ему имя.


ARK>А есть ли — в разрезе кеширования — отличие от обертки у этого подхода?


S>>Но это не есть закэшировал. Это именно что обертка. Аналог хаскеля был бы таким

S>>
S>>Action putStrLn1 = () => Console.WriteLine("query");
S>>


ARK>Так это то же самое же.

Нет, т.к. результат вычисления твоей putStrLn1 нельзя закэшировать. Он void + грязь.

ARK>>>UPD. Я понимаю, что это немного другое. Но суть та же — результатом "кеширования" putStr является отложенное действие.

S>>Но у тебя оно именно что не отложенное.

ARK>Почему, любая функция — это отложенное действие. Просто в моем варианте есть выбор, когда вызвать это "отложенное действие". А в хаскеле такого выбора нет — оно будет вызвано кем-то извне. Вот и вся разница.

Нет, разница еще и в том, что в хаскеле функция (любая) не есть действие. Семантически функция — это "это".


S>>да, четкое. Пример — id.


ARK>id, согласно моему критерию (а не твоей трактовке моего критерия), является чистой. У нее нет синтаксической метки грязи и в документации не сказано, что она делает грязь.

Даже если с учетом того, что она может возвращать IO (не только лишь принимать его)?

ARK>>>Мне нравится такое определение, которое не требует внешних зависимостей от окружения.

S>>А разве определение в википедии требует? Разве оно как-то намекает на то, что оператор сложения стал грязным от того, что грязное окружение фиксирует изменения регистров процессора? Или что если консоль перенаправили в dev/null, то это сделало любой консольный вывод чистым?

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

Опять-таки, если в коде условного оператора сложения строк или еще чего-то не написано дергать функции ОСи или окружения, но окружение при выполнении этого оператора само что-то дергает для отладки или слежения, то проблема ли это чистоты оператора сложения? Ведь он-то сам лишнего не дергает. Он чист и пользоваться его чистотой мы можем в полной мере, если исключим из внимания инициативу окружения, которая будет записывать что-то про регистры CPU в файл. Нам для разработки программы такая функция окружения может быть и вовсе неизвестна. Какой смысл концентрироваться на ней, избегая кэширования или переставления ?
Re[115]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 12:47
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, samius, Вы писали:


ARK>>>Функция из unit в unit?

S>>Элементы какого множества в какое она отображает?

ARK>Пустого в пустое.

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

S>>Признаком чистоты чего именно? Функция, возвращающая лямбду с завернутой printf — будет чиста как и putStr. Но сам printf от этого чище не стал.


ARK>ОК. Тут согласен. Эквилибристика хаскеля заключается в том, что обертка создается "внутри", но формально прямого аналога в С нет. Однако можно считать, что printf возвращает обертку, но не с захваченными аргументами, как у хаскеля, а со всеми теми же. Глупый трюк, зато так можно тоже считать printf чистой.


Сова, натянутая на глобус, только и всего. Ни глобус, ни сова, ни printf, не стали обладать новыми полезными качествами.
Re[107]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 12:48
Оценка:
Здравствуйте, samius, Вы писали:

ARK>>

ARK>>As a concession to practicality, a pure function can also:

ARK>> read and write the floating point exception flags
ARK>> read and write the floating point mode flags, as long as those flags are restored to their initial state upon function entry
ARK>> perform impure operations in statements that are in a ConditionalStatement controlled by a DebugCondition.


S>ИИИ?


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


ARK>>D не полагается на вычислитель при определении чистоты. В D функция чиста, если имеет модификатор "pure".

S>Все совершенно не так. В D функция может быть объявлена как pure, если удовлетворяет условиям. Соответственно, формально чистая функция, не помеченная pure, все равно будет ей оставаться. Синус не станет грязнее, если ты не пометишь его флагом.

С точки зрения языка чистые функции, не помеченные pure, не отличаются от нечистых. То есть к ним никакие оптимизации применяться не будут. И программист не имеет права закладываться на чистоту, если слова pure нет.

А вот если оно есть, то:

An implementation may assume that a pure function that (a) accepts only parameters without mutable indirections, and (b) returns a result without mutable indirections, will have the same effect for all invocation with equivalent arguments, and is allowed to memoize the result of the function under the assumption that equivalent parameters always produce equivalent results. Such functions are termed strongly pure functions in this document.

A pure function that has no parameter with mutable indirections is called "strongly pure" and fulfills the purity definition in traditional functional languages.


"pure" выделено болдом, т.е. речь идет не просто о прилагательном, а о модификаторе языка.

ARK>>Я не про чистоту DrawPoint, а в общем — про контракты функций. Чистота — один частный случай. Вопрос был — ты что, проверяешь вообще всё, все аргументы и все эффекты всех функций? Если нет, то почему тебе недостаточно просто сигнатуры и/или документации для того, чтобы рассуждать о чистоте функции?

S>Обычно достаточно, но я знаю, что они могут противоречить друг другу и действительности.

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

ARK>>Да, или окружение. Еще раз вернусь в изначальное русло: я использую виртуальную машину для демонстрации того, что определение чистоты из википедии при написании кода является не слишком полезным, поскольку оно опирается на такие признаки, которые могут быть подделаны.

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

Как ты узнаешь, предписывает функция окружению гадить или нет? Она вызывает функции, которые, по твоему мнению (чуйка?), предписывают окружению гадить?

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

S>Вызов хаскельной putStr возвращает не обертку, а IO. Но да, можно назвать ее оберткой. Это как C++ возвращал бы function, C# Action и т.п. Но вызов этой обертки не приводит к вызову putStr снова, т.к. putStr уже отработала, вернув обертку.
S>Когда ты оборачиваешь printf, то ты возвращаешь обертку, которая при вызове передаст управление в printf, как IO передаст управление в грязный экшн. Функции putStr и printf при этом на разных этажах находятся.

Верно. Про обертку написал в другом посте.
Re[110]: Мнение: объектно-ориентированное программирование —
От: artelk  
Дата: 13.11.19 12:59
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, artelk, Вы писали:


A>>Формально в Хаскеле все I/O функции являются чистыми.

A>>"Но мы-то знаем (C)", что это всего лишь хитрый математический трюк, позволяющий представить функции, взаимодействующие с изменяемым миром, в виде чистых функций.
ARK>Вокруг этого трюка весь сыр-бор. Формально можно точно так же утверждать, что в С все функции тоже чистые, просто имеют неявный скрытый параметр "мир" на входе (или, аналогично хаскелю, возвращают IO-действия). Просто в хаскеле IO — это подмножество всех функций, а в С — это будут вообще все функции, без исключения. Ура, язык С — чист, как хаскель.

Это очень смелый мысленный эксперимент Вопрос о практической ценности такого подхода. Для практики нам хотелось бы в отношении некоторых функций иметь гарантии, что они работают как функции в математическом смысле. Их результат зависит только от значений параметров, так что их можно легко тестировать, можно кэшировать результаты. Они не имеют побочных эффектов, так что можно параллелить вычисления. Скрытый параметр "мир" будет мешать.
Re[111]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 13:07
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Удовлетворяет, т.к. принимает IO. Но она чистая. Привести пример на хаскеле о том, что id принимает IO?

ARK>>Не уверен, что в определении Sinclair речь идет только о хаскеле. Оно общего вида. Если функция помечена соответствующим образом — она грязная (или, наоборот, чистая).
S>Не уверен, что можно сформулировать "принимает IO" в общем виде. printf никакого IO не принимает и ничем не помечен.

Можно, почему нет. printf принимает и возвращает скрытый параметр "мир" (вполне можно так формализовать).

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

S>Здрасте. А что мне в id мешает засунуть unsafe? Одной сигнатуры недостаточно.

Мой поинт в том, что для рассуждений о чистоте — достаточно сигнатуры. Остальное проверить нельзя.

ARK>>Да, тут ошибка. Под "принимает IO" имеется в виду "имеет метку IO", что для хаскеля является эквивалентом _возврата_ IO.

ARK>>А для какого-нибудь Clean "меткой IO" является уникальный тип "World", причем и на входе, и на выходе.
ARK>>В общем да, со словом "принимает" тут не вполне корректное определение.
S>Но это не определение, это лишь метка. Не метка делает функцию чистой или грязной.

Да, метка. Метки бывают разные, например "pure" или слово в документации. Прикол в том, что именно "метка" и определяет чистоту. Или что для тебя делает UnsafePerformIO грязным? Ты его "проверяешь"? Но не в виртуальной машине, ведь это нечестно?

ARK>>Так это то же самое же.

S>Нет, т.к. результат вычисления твоей putStrLn1 нельзя закэшировать. Он void + грязь.

Почему, можно. Есть прямое преобразование к Action.

ARK>>id, согласно моему критерию (а не твоей трактовке моего критерия), является чистой. У нее нет синтаксической метки грязи и в документации не сказано, что она делает грязь.

S>Даже если с учетом того, что она может возвращать IO (не только лишь принимать его)?

Да. Здесь вопрос в слове "может". Грязная (в случае хаскеля) — это когда "обязательно возвращает", а не "может возвращать".

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

S>Опять-таки, если в коде условного оператора сложения строк или еще чего-то не написано дергать функции ОСи или окружения, но окружение при выполнении этого оператора само что-то дергает для отладки или слежения, то проблема ли это чистоты оператора сложения? Ведь он-то сам лишнего не дергает. Он чист и пользоваться его чистотой мы можем в полной мере, если исключим из внимания инициативу окружения, которая будет записывать что-то про регистры CPU в файл. Нам для разработки программы такая функция окружения может быть и вовсе неизвестна. Какой смысл концентрироваться на ней, избегая кэширования или переставления ?

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

Ну и вопросы, собственно, остались без ответа (выделено).
Re[112]: Мнение: объектно-ориентированное программирование —
От: artelk  
Дата: 13.11.19 13:07
Оценка: +1
Здравствуйте, samius, Вы писали:

S>Здравствуйте, artelk, Вы писали:


A>>Ок,

A>>1. Функция НЕ является "грязной", если она не возвращает IO и не делает unsafe штук
A>>Все остальные функции потенциально "грязные".

S>Хорошо, но еще пусть это будет не определением (definition), а неким критерием, сформулированным для хаскеля на основе классического определения чистоты с учетом системы типов и бэкдоров хаскеля.


Для хаскеля на основе классического определения чистоты достаточно только неиспользования unsafe.
Для хаскеля в качестве определения, имеющего практическую ценность я предложил такое: "Грязность" функции это ее возможность иметь побочные эффекты в виде транформации Мира либо если результат ее вычисления зависит от состояния Мира.
Re[116]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 13:12
Оценка:
Здравствуйте, samius, Вы писали:

ARK>>>>Функция из unit в unit?

S>>>Элементы какого множества в какое она отображает?
ARK>>Пустого в пустое.
S>Пустое множество — это множество, не содержащее ни одного элемента. Так что, я не понимаю, как можно отображать элементы пустого множества. Если бы функция принимала множество (пустое, например), то это было бы другое дело.

ОК. Множество, содержащее пустое множество, отображается в множество, содержащее пустое множество.

S>>>Признаком чистоты чего именно? Функция, возвращающая лямбду с завернутой printf — будет чиста как и putStr. Но сам printf от этого чище не стал.

ARK>>ОК. Тут согласен. Эквилибристика хаскеля заключается в том, что обертка создается "внутри", но формально прямого аналога в С нет. Однако можно считать, что printf возвращает обертку, но не с захваченными аргументами, как у хаскеля, а со всеми теми же. Глупый трюк, зато так можно тоже считать printf чистой.
S>Сова, натянутая на глобус, только и всего. Ни глобус, ни сова, ни printf, не стали обладать новыми полезными качествами.

Верно. Это нелепо. Таким же нелепым лично мне кажется утверждение о чистоте IO-функций в хаскеле/клине/etc. Впрочем, это уже 100 раз было обсуждено здесь.
Re[108]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 13:15
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, samius, Вы писали:


ARK>>>

ARK>>>As a concession to practicality, a pure function can also:

ARK>>> read and write the floating point exception flags
ARK>>> read and write the floating point mode flags, as long as those flags are restored to their initial state upon function entry
ARK>>> perform impure operations in statements that are in a ConditionalStatement controlled by a DebugCondition.


S>>ИИИ?


ARK>

ARK>Ну, разработчики D как минимум не используют определение чистоты из википедии.
ARK>На мой взгляд, тот подход, который у них, вполне соответствует моему пониманию чистоты. Впрочем, я не настаиваю, это для меня не очень важно. Важнее отказ от википедийного определения.


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

ARK>>>D не полагается на вычислитель при определении чистоты. В D функция чиста, если имеет модификатор "pure".

S>>Все совершенно не так. В D функция может быть объявлена как pure, если удовлетворяет условиям. Соответственно, формально чистая функция, не помеченная pure, все равно будет ей оставаться. Синус не станет грязнее, если ты не пометишь его флагом.

ARK>С точки зрения языка чистые функции, не помеченные pure, не отличаются от нечистых. То есть к ним никакие оптимизации применяться не будут. И программист не имеет права закладываться на чистоту, если слова pure нет.

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

ARK>А вот если оно есть, то:

ARK>

An implementation may assume that a pure function that (a) accepts only parameters without mutable indirections, and (b) returns a result without mutable indirections, will have the same effect for all invocation with equivalent arguments, and is allowed to memoize the result of the function under the assumption that equivalent parameters always produce equivalent results. Such functions are termed strongly pure functions in this document.

ARK>A pure function that has no parameter with mutable indirections is called "strongly pure" and fulfills the purity definition in traditional functional languages.


ARK>"pure" выделено болдом, т.е. речь идет не просто о прилагательном, а о модификаторе языка.

ну так и const модификатор в C++. И что?

ARK>>>Я не про чистоту DrawPoint, а в общем — про контракты функций. Чистота — один частный случай. Вопрос был — ты что, проверяешь вообще всё, все аргументы и все эффекты всех функций? Если нет, то почему тебе недостаточно просто сигнатуры и/или документации для того, чтобы рассуждать о чистоте функции?

S>>Обычно достаточно, но я знаю, что они могут противоречить друг другу и действительности.

ARK>Это нормально, как и аргументы могут быть перепутаны. Только вот смысла проверять все это — никакого (за исключением случаев, когда есть основания подозревать, что что-то не так), а иногда и не только смысла, но и возможности нет. При этом "декларативная" чистота при программировании всегда остается полезной, как и другие контракты.

С этим никаких проблем.

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


ARK>Как ты узнаешь, предписывает функция окружению гадить или нет? Она вызывает функции, которые, по твоему мнению (чуйка?), предписывают окружению гадить?

Большую чуйку не нужно иметь, что бы понять, что SendMessageA какая-нибудь что-то отчебучит, кроме возврата кода ошибки. Что-то такое, чего от синуса ждать не приходится.
Re[111]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 13:19
Оценка:
Здравствуйте, artelk, Вы писали:

A>Вопрос о практической ценности такого подхода.


В основном нулевая. Единственная ценность — провести параллели с "чистыми" IO-функциями в хаскеле.

A>Для практики нам хотелось бы в отношении некоторых функций иметь гарантии, что они работают как функции в математическом смысле. Их результат зависит только от значений параметров, так что их можно легко тестировать, можно кэшировать результаты. Они не имеют побочных эффектов, так что можно параллелить вычисления. Скрытый параметр "мир" будет мешать.


Это, разумеется, провернуть не выйдет — ведь каждая функция в С теперь требует "мира", а нам его взять просто неоткуда. Поэтому мы вынуждены довольствоваться тем, что есть — запускать все сишные программы через "грязный вычислитель", у которого мир есть. Ни кешировать, ни параллелить, ничего. Зато все функции — чистые!

Но разве в хаскеле не то же самое? Мы можем "протестировать" функцию putStr и убедиться, что она возвращает action. Но мы хотим вовсе не это протестить, мы хотим вывести на консоль строку! Велкам ту риэл ворлд, Нео — запускай грязный вычислитель, никаких кешей и параллельности. Все, как в С.
Re[112]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 13:25
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, samius, Вы писали:


ARK>>>Не уверен, что в определении Sinclair речь идет только о хаскеле. Оно общего вида. Если функция помечена соответствующим образом — она грязная (или, наоборот, чистая).

S>>Не уверен, что можно сформулировать "принимает IO" в общем виде. printf никакого IO не принимает и ничем не помечен.

ARK>Можно, почему нет. printf принимает и возвращает скрытый параметр "мир" (вполне можно так формализовать).

Не думаю, что Sinclair подразумевал это в своем определении.

S>>Здрасте. А что мне в id мешает засунуть unsafe? Одной сигнатуры недостаточно.


ARK>Мой поинт в том, что для рассуждений о чистоте — достаточно сигнатуры. Остальное проверить нельзя.

LRESULT SendMessage(
  HWND   hWnd,
  UINT   Msg,
  WPARAM wParam,
  LPARAM lParam
);

Что скажешь о чистоте по одной лишь сигнатуре с учетом того, что printf "чистая"? Вероятно, тоже будет чистой.

S>>Но это не определение, это лишь метка. Не метка делает функцию чистой или грязной.


ARK>Да, метка. Метки бывают разные, например "pure" или слово в документации. Прикол в том, что именно "метка" и определяет чистоту. Или что для тебя делает UnsafePerformIO грязным? Ты его "проверяешь"? Но не в виртуальной машине, ведь это нечестно?

unsafePerformIO указывает на то, что функция с большой вероятностью либо берет данные из мира, либо кладет туда данные. Иначе зачем ей там быть?

ARK>>>Так это то же самое же.

S>>Нет, т.к. результат вычисления твоей putStrLn1 нельзя закэшировать. Он void + грязь.

ARK>Почему, можно. Есть прямое преобразование к Action.

преобразование к Action не выполняет код. Это не результат вызова. Это взятие "адреса".

ARK>>>id, согласно моему критерию (а не твоей трактовке моего критерия), является чистой. У нее нет синтаксической метки грязи и в документации не сказано, что она делает грязь.

S>>Даже если с учетом того, что она может возвращать IO (не только лишь принимать его)?

ARK>Да. Здесь вопрос в слове "может". Грязная (в случае хаскеля) — это когда "обязательно возвращает", а не "может возвращать".

Я только напомню, что putStr в случае хаскеля — чистая, хоть и возвращает IO.

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

S>>Опять-таки, если в коде условного оператора сложения строк или еще чего-то не написано дергать функции ОСи или окружения, но окружение при выполнении этого оператора само что-то дергает для отладки или слежения, то проблема ли это чистоты оператора сложения? Ведь он-то сам лишнего не дергает. Он чист и пользоваться его чистотой мы можем в полной мере, если исключим из внимания инициативу окружения, которая будет записывать что-то про регистры CPU в файл. Нам для разработки программы такая функция окружения может быть и вовсе неизвестна. Какой смысл концентрироваться на ней, избегая кэширования или переставления ?

ARK>Совершенно верно, посторонняя активность — это не проблема оператора сложения. И пользоваться его чистотой (декларируемой) мы можем, это как раз то, о чем я говорю. Но и тут тот же вопрос — что такое "лишнее", что может дернуть оператор сложения? Откуда мы знаем, "лишняя" функция или нет?


ARK>Ну и вопросы, собственно, остались без ответа (выделено).

Ты так и не дошел до википедии? Там есть статья, ссылка на странице чистоты функции.
Re[113]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 13:26
Оценка:
Здравствуйте, artelk, Вы писали:

A>Здравствуйте, samius, Вы писали:


S>>Хорошо, но еще пусть это будет не определением (definition), а неким критерием, сформулированным для хаскеля на основе классического определения чистоты с учетом системы типов и бэкдоров хаскеля.


A>Для хаскеля на основе классического определения чистоты достаточно только неиспользования unsafe.

A>Для хаскеля в качестве определения, имеющего практическую ценность я предложил такое: "Грязность" функции это ее возможность иметь побочные эффекты в виде транформации Мира либо если результат ее вычисления зависит от состояния Мира.

Хорошо, согласен.
Re[109]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 13:27
Оценка:
Здравствуйте, samius, Вы писали:

S>По-моему ты путаешь немного определение чистоты и объяснение флага в языке.


А разве в языке есть отдельное понятие "чистая функция", не описываемое флагом? По-моему, эти вещи взаимозаменяемы и употребляются вместе: https://dlang.org/spec/function.html#pure-functions

ARK>>С точки зрения языка чистые функции, не помеченные pure, не отличаются от нечистых. То есть к ним никакие оптимизации применяться не будут. И программист не имеет права закладываться на чистоту, если слова pure нет.

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

Если пометить, то появится, мемоизация начнет работать. Функции без "pure" — с точки зрения языка равны грязным. Язык отделяет чистые функции от грязных, и делает это на основе модификатора "pure".

ARK>>Это нормально, как и аргументы могут быть перепутаны. Только вот смысла проверять все это — никакого (за исключением случаев, когда есть основания подозревать, что что-то не так), а иногда и не только смысла, но и возможности нет. При этом "декларативная" чистота при программировании всегда остается полезной, как и другие контракты.

S>С этим никаких проблем.

То есть декларативная (указанная в сигнатуре или документации) чистота полезна всегда (как один из контрактов функции)?

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

ARK>>Как ты узнаешь, предписывает функция окружению гадить или нет? Она вызывает функции, которые, по твоему мнению (чуйка?), предписывают окружению гадить?
S>Большую чуйку не нужно иметь, что бы понять, что SendMessageA какая-нибудь что-то отчебучит, кроме возврата кода ошибки. Что-то такое, чего от синуса ждать не приходится.

Но все равно это чуйка. А формальный критерий есть? "Лишние" функции — это случайно не те функции, которые постулированы (документацией или модификаторами) как грязные?
Re[117]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 13:34
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, samius, Вы писали:


S>>Пустое множество — это множество, не содержащее ни одного элемента. Так что, я не понимаю, как можно отображать элементы пустого множества. Если бы функция принимала множество (пустое, например), то это было бы другое дело.


ARK>ОК. Множество, содержащее пустое множество, отображается в множество, содержащее пустое множество.

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

S>>Сова, натянутая на глобус, только и всего. Ни глобус, ни сова, ни printf, не стали обладать новыми полезными качествами.


ARK>Верно. Это нелепо. Таким же нелепым лично мне кажется утверждение о чистоте IO-функций в хаскеле/клине/etc. Впрочем, это уже 100 раз было обсуждено здесь.

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