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

S>>>Я понял. Ты предлагаешь один и тот же "синус" выполнить грязно и чисто. Но причем тут "синус"? Ты переключился с чистоты кода на чистоту исполнения.

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

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

Согласно моему подходу, чистые функции — это те функции, которые мы ДЕКЛАРИРОВАЛИ как чистые. Чисты ли будут вызовы таких функций, или не чисты — неважно.
Соответственно, "декларативно чистая" функция — это функция, которая задекларирована как чистая. Во всех известных мне языках под "чистыми" функциями понимаются именно "декларативно чистые".

Декларировать чистоту функции можно несколькими способами.

1) Сигнатура функции. Самый надежный способ. Встроенные функции имеют сигнатуру, заданную аксиоматически, а построенные поверх них — уже определенную из исходного кода тел этих функций. Варианты сигнатур: ключевое слово "pure" в D, IO-монада в Haskell (декларируется наоборот грязь), "function" в Ada-83 и т.д.

2) Документация. Из сигнатуры понять нельзя, но в документации явно указано, что функция чиста (декларативно, разумеется!). Менее надежный способ, т.к. компилятор нам уже ничего не подскажет, если документация устарела.

3) Просмотр исходного кода / вера / чуйка / etc. Самый ненадежный способ. Мы имеем некоторые основания предполагать, что функция чиста (опять же, декларативно — ибо никто не запретит нам ее запустить в виртуальной машине и получить ввод-вывод на этой якобы чистой функции). Но эти основания не подкреплены ничем.

S>>>Причем тут вера? В евклидовой геометрии параллельными прямыми на плоскости называются непересекающиеся прямые.

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

Почему этот перечень должен там быть? Он не часть определения.

ARK>>Ты знаешь постулированную кем-то (декларативную) чистоту синуса. Реальную ты не знаешь. Я могу легко написать свою грязную реализацию синуса.

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

И каким же образом? Открыл его код, ищешь там функции, которые считаешь грязными (почему ты их считаешь грязными, отдельный вопрос)? Запустил, ожидаешь вывод картинки на принтер или вывод в консоль? Предположим, не увидел ни того, ни другого. Все, после этого ты ВЕРИШЬ, что синус чист? Я правильно описал процедуру определения чистоты?

ARK>>Разница такая, что я с ней обращаюсь в коде как с чистой. Я считаю, что ввода-вывода в ней нет, и строю код, исходя из этого предположения. То же самое делает и компилятор, видя флаг "pure" (или отсутствие параметра "IO"). Мой код корректен относительно заданных этой функцией инвариантов. Есть там внутри реально ввод-вывод или нет — меня не интересует. Это слой абстракции. Абстракция позволяет справиться со сложностью и писать корректный код. Если инвариант, предоставляемый функцией, нарушается, то это проблема этой функции, а не моего кода. Я или заменю эту функцию на корректную, или перепишу код иным образом. Проверять контракты всех функций — нелепо. Чистота — это один из контрактов.


S>Вот это хорошо сказал. Ну то есть, всем не пофиг. Сложно пользоваться функций, если не представляешь или не в полной мере представляешь ее контракты. Что она портит, что берет помимо аргументов, от чего зависит результат (не только лишь возвращаемый, но и изменения в окружении). Т.е. еще один способ судить о чистоте функции (не исчерпывающий, разумеется) — анализ чистоты контракта.


Кроме контракта, ни о каких вариантах чистоты судить или нет смысла, или невозможно. Контракт может быть задан разными способами (см. выше).

S>>>>>Вызов грязной функции не может быть bind-ом, т.к. bind не вызывает ничего, только связывает.

ARK>>>>Ну а если абстрагироваться и представить, что "f();" — это не вызов, а связывание?
S>>>Связывание, которое в момент вызова гадит в мир? Давай просто абстрагируемся от того, что f() гадит в мир и скажем, что всем пофиг?
ARK>>Оно не гадит в момент связывания. А гадит, когда "внешний вычислитель" это запустит. В точности, как в хаскеле.
S>Передает ли внешний вычислитель при этом управление printf-у? Если да, то грязь появляется до или после возврата управления?

Идеологически — не передает, а передает управление action'у, который вернул printf. Ой, а как же напрямую вызвать action, который возвращает printf, как это выразить в коде? Никак. Ровно то же самое, что в хаскеле.

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

ARK>>Что такое "грязь" в коде? Это вызов функций, которые ты считаешь грязными? А почему ты их считаешь грязными? Потому что это написано в документации?
S>Давай попробуем разобраться хотя бы в чистоте контракта State. Нужна ли грязь для его реализации?

Ты все же скажи, как ты видишь "грязь в коде".

S>Нужна ли грязь для его реализации?


Нужна, для телеметрии. Я разработчик нового компилятора Haskell и хочу дать пользователям возможность писать такие программы, активность которых можно при желании контролировать удаленно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.