Re[101]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 12.11.19 07:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>Я же показал вроде, в чём разница между функциями, которые работают с миром, и функциями, которые работают с функциями, которые работают с миром.
S>Функция square по-прежнему является чистой, даже когда она возводит в квадрат грязную функцию. Например, результат square(sin, 10) можно кэшировать.

Можно считать, что printf тоже возвращает функцию, которая работает с миром. Это маразм, но это вполне укладывается в модель хаскеля.

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

S>Это определение проверить очень легко: если у функции нет в аргументах IO, то она никак не может делать ввода-вывода.
S>Наличие unsafePerformIO — это специальная штука, которая на наше понимание чистоты не влияет.
S>Примерно так же, как то, что глагол GET в HTTP является безопасным: он по дизайну не может иметь побочных эффектов.
S>На практике это работает несколько наоборот: иметь-то он эти эффекты, конечно же, может (а кто ему запретит?), вот только полагаться на них мы не можем.
S>То есть, к примеру, если, допустим, мы сделаем так, что GET возвращает нам JS-объект {"name":"sinclair", "visitCount":42}, и будем инкрементировать visitCount при каждом исполнении, то не надо плакать, когда от нажатия F5 в браузере счётчик не растёт. Потому, что инфраструктура считает глагол безопасным, и имеет право брать результат из кэша.
S>Так и тут — если мы хотим сделать версию синуса, которая логгирует все вызовы, то можно либо сделать внутри неё unsafePerformIO — и тогда у нас количество и порядок строчек лога не будет детерминировано, либо по-честному вмешать в её сигнатуру IO, и тогда придётся честно выписывать порядок вычислений при её использовании.



Теперь бы это понимание донести до samius.
Re[101]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 12.11.19 08:06
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Я абсолютно согласен с таким подходом. Если функция обращается к миру — она грязная.

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

Единственно разумный подход — считать, что это грязь. Это как раз о том, что говорит Sinclair. "Реальную грязь" ты не определишь никак, пишу это в очередной раз. Ты получишь разную картину для одной и той же функции в разных окружениях.

S>Тем более, что putStr не принимает IO.


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

ARK>>Если бы ты мог в коде на хаскеле "оторвать" саму putStr от функции, которую она возвращает (вызвать putStr, но не вызывать то, что она возвращает, или вызвать этот action потом и из другого места), то разница с С была бы. Но ты не можешь.

S>Ну так может быть это и можно. Я просто курил Хаскель лет 10 назад последний раз. Судя по типу — они именно оторваны, т.к. putStr не принимает IO, не принимает RealWorld. Она принимает string.

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

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

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

В общем-то этим определением ничего проверить нельзя. Оно годится максимум для общего представления, что такое чистота. Когда дело доходит до программирования, важны контракты функций. Абстракции.
Re[90]: Мнение: объектно-ориентированное программирование —
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 12.11.19 08:56
Оценка:
Здравствуйте, samius, Вы писали:

I>> Часть вещей следует из определения, а именно "деятельность для гарантированного подтверждения"

S>Любая плановая и систематическая.

Именно, плановая, систематическая, цель которой — гарантированное подтверждение. Если ты не достиг цели, о качестве вообще нет смысла говорить. А если достиг, то у тебя есть точные сведения о том, какое именно качество — высокое, низкое, среднее. И если цель не достигнута, то процесс строится так, что бы получить внятное обоснование, где препятствие и как его устранить.
Если вдруг обнаруживается, что цель недостижима, то ты получаешь гарантию — установить качество не представляется возможным.

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

S>В определении нет речи об обещаниях. Освежи-ка его. Подтверждение соответствия требованиям. Все.

А что по твоему есть "гарантированное подтверждение" ?

I>>Ок. Теперь покажи т.н. анализ ожиданий, логическую цепочку.

S>Твой критерий не требует анализа. Он основывался на успехе. Если успех есть — то есть гарантия, нет успеха — значит, он недостижим.

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

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

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

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

I>> Ок, покажи пример, как заскриптовать нечто неизвестное на момент написания скрипта, включая все сорта расширений — база знаний и тд и тд и тд. Скажем, сегодня ты пишешь скрипт, а завтра мы узнаем скажем, неожиданные требования и не сразу, а во время работы этого самого скрипта.

S>Про неизвестное — ты тоже выдумал. "что производимые товары, услуги, выполняемые процессы соответствуют установленным требованиям". Установленным здесь в прошедшем времени. Нет никаких гарантий соответствия неизвестным и неожиданным требованиям. И быть не может.

Ок, то есть, сказать нечего.

I>>Или так — ты заскриптуешь тот самый фактор, который случился у меня 8 лет назад во время прогона перформанс тестов, когда я только-только начал подогревать энвайрмент. Всё шло штатно, штанее некуда — все счетчики идеально ложились на ожидаемые результаты. Но прогон пришлось принудительно остановить. Вот покажи, пример скрипта. Потом мы вместе проверим, насколько хорош твой скрипт

S>Когда будут известны требования

Ты ведь сказал — что можешь заскриптовать неизвестное. Покажи пример одного единственного фактора, неизвестного на момент скриптования(расширения, дополнения).

I>>Можешь иначе, текстом — сегодня или завтра, на крайняк до конца сего месяца, напиши сюда нечто, о чем ты ни разу не слышал, не видел, не подозревал с начала жизни и будешь ни видеть, ни слышать, ни подозревать вплоть до начала 2020

S>И часто ты гарантированно подтверждаешь нечто, "о чем ты ни разу не слышал, не видел, не подозревал с начала жизни и будешь ни видеть, ни слышать, ни подозревать вплоть до начала 2020 "

Всегда. Я всем говорю, что в софте гарантированно есть неожиданные баги. Чем слабее тестирование, тем выше шанс на них нарваться.
Re[102]: Мнение: объектно-ориентированное программирование —
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.11.19 08:57
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Можно считать, что printf тоже возвращает функцию, которая работает с миром. Это маразм, но это вполне укладывается в модель хаскеля.

Результат printf() можно кэшировать?

ARK>Теперь бы это понимание донести до samius.

Не вижу, чтобы он этого не понимал.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[103]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 12.11.19 09:03
Оценка:
Здравствуйте, Sinclair, Вы писали:

ARK>>Можно считать, что printf тоже возвращает функцию, которая работает с миром. Это маразм, но это вполне укладывается в модель хаскеля.

S>Результат printf() можно кэшировать?

А результат вызова putStr можно кэшировать?

ARK>>Теперь бы это понимание донести до samius.

S>Не вижу, чтобы он этого не понимал.

Вся дискуссия проистекает из факта, что он этого не понимает. Или понимает, но не признает.
Re[104]: Мнение: объектно-ориентированное программирование —
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 12.11.19 09:30
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>>>Теперь бы это понимание донести до samius.

S>>Не вижу, чтобы он этого не понимал.

ARK>Вся дискуссия проистекает из факта, что он этого не понимает. Или понимает, но не признает.


Второе. Обычная его тактика. За 10 лет ничего не изменилось.
Re[2]: Мнение: объектно-ориентированное программирование — катастрофа на триллио
От: jahr  
Дата: 12.11.19 10:13
Оценка:
Здравствуйте, AlexRK, Вы писали:


ARK>Правильный функциональный язык — на поверхностном уровне — ДОЛЖЕН мимикрировать под C/Pascal!!!


Так плюсы вполне себе позволяют писать в функциональном стиле, упарывайся как хочешь. И с каждой новой версией поддержка функциональщины все лучше.)
Re[97]: Мнение: объектно-ориентированное программирование —
От: artelk  
Дата: 12.11.19 15:48
Оценка: 74 (1)
Здравствуйте, Sinclair, Вы писали:

S>Но! Мы можем построить функцию sinsquared двумя способами:

S>
public (number, IO) sinsquared((number x, IO world))
S>{
S>  (var y, var world2)=sin(x, world);
S>  (var r, var world3)=sin(x, world2);
S>  return (r*y, world3);
S>});

S>public Function<IO, (number, IO)> sinsquared(number x)=>(IO world)=>
S>{
S>  (var y, var world2)=sin(x, world);
S>  (var r, var world3)=sin(x, world2);
S>  return (y*r, world3);
S>});
S>

S>В первом случае мы получаем грязную функцию, т.к. она обращается к IO. Во втором — чистую, т.к. сама она к IO не обращается, но строит функцию, которая обращается к IO.

Но вы просто явно сделали карринг. В ФП языках он делается автоматически. А если точнее: первый способ построения функции, с точки зрения компилятора, это просто укороченный способ для второго, оба способа тождественны. Я не согласен, что именно факт отложенности выполнения (до момента, когда передадут world) играет какую-то существенную роль в вопросе сохранения чистоты ФП языка при добавлении ему возможности взаимодействия с внешним "грязным" миром. Главным в этом вопросе является то, что "мир" передается явно и все функции, взаимодействующие с миром, принимают и возвращают его. Еще полезным было бы как-то на уровне системы типов сделать трюк, запрещающий сохранение текущего состояния мира в переменной с последующим переиспользованием. На сколько понимаю, именно для этого сделали, что "IO a" это тип функций, взаимодействующих с миром, а не тип, хранящий сам мир. "Инстанс" мира глубоко спрятан и недоступен.
Re[98]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 12.11.19 20:46
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


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


ARK>Это то, что следует из твоего подхода. Выполняет ли фактически функция ввод-вывод или нет — от нее вообще не зависит.

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

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


ARK>Да. Это задано аксиоматически. То же самое и с чистотой (как минимум на уровне встроенных функций).

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

S>>Согласен, по-строгому надо доказывать. Но это может работать в обе стороны. Утверждаешь, что putStr грязная — докажи.


ARK>Либо доказывать, либо постулировать.


ARK>Чтобы утверждать что-либо о putStr, необходимо формализовать определения. Что есть "чистая", что есть "грязная", что есть "вызов", как отделить одно от другого. Иначе можно, жонглируя словами, спорить бесконечно.


У нас нет единого понятийного аппарата. О каком споре речь?

S>>Дак как же не определить? что с синусом-то не понятно?


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

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

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


Мы не можем, но я — могу и пользуюсь.

S>>А раз всем пофиг, то вообще какая ТЕБЕ разница, чистая функция или нет?


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


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

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

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

ARK>Оно не гадит в момент связывания. А гадит, когда "внешний вычислитель" это запустит. В точности, как в хаскеле.

Передает ли внешний вычислитель при этом управление printf-у? Если да, то грязь появляется до или после возврата управления?

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


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

Давай попробуем разобраться хотя бы в чистоте контракта State. Нужна ли грязь для его реализации?
Re[102]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 12.11.19 20:58
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


S>>Нет, не согласен. См. определение. Принимать IO — еще не грязь.


ARK>Единственно разумный подход — считать, что это грязь. Это как раз о том, что говорит Sinclair. "Реальную грязь" ты не определишь никак, пишу это в очередной раз. Ты получишь разную картину для одной и той же функции в разных окружениях.


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


S>>Тем более, что putStr не принимает IO.


ARK>Если в коде нет возможности отделить вызов функции от вызова того, что она возвращает, то эти вещи изоморфны друг другу.

Я бы не настаивал на том, что возможности нет, раз такая возможность используется для отделения чистоты от грязи. Ну и в конце концов — принимать IO и возвращать — не одно и то же. Или тут тоже проблема?

ARK>>>Если бы ты мог в коде на хаскеле "оторвать" саму putStr от функции, которую она возвращает (вызвать putStr, но не вызывать то, что она возвращает, или вызвать этот action потом и из другого места), то разница с С была бы. Но ты не можешь.

S>>Ну так может быть это и можно. Я просто курил Хаскель лет 10 назад последний раз. Судя по типу — они именно оторваны, т.к. putStr не принимает IO, не принимает RealWorld. Она принимает string.

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

"Наша грязная функция" — вот это ты как определил? Ты меня убеди сначала, что она грязная. Хотя нет, давай сначала разберемся с критерием. А то у тебя выходит что id грязный, так нам чистоту putStr не получить.

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


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


Толку от контрактов, если у тебя id грязная?
Re[91]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 12.11.19 21:13
Оценка:
Здравствуйте, Ikemefula, Вы писали:

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


I>>> Часть вещей следует из определения, а именно "деятельность для гарантированного подтверждения"

S>>Любая плановая и систематическая.

I>Именно, плановая, систематическая, цель которой — гарантированное подтверждение. Если ты не достиг цели, о качестве вообще нет смысла говорить. А если достиг, то у тебя есть точные сведения о том, какое именно качество — высокое, низкое, среднее. И если цель не достигнута, то процесс строится так, что бы получить внятное обоснование, где препятствие и как его устранить.

Ну, а что если цель достичь подтверждения в 2050-м году?
I>Если вдруг обнаруживается, что цель недостижима, то ты получаешь гарантию — установить качество не представляется возможным.
И как ты обнаружишь что цель недостижима? Вот я буду 1 день в году посвящать плановой и систематической деятельности, цель которой — гарантированное подтверждение соответствия. В соответствии с определением — это и есть контроль качества. Но ты еще требуешь достижимости. Вот и доказывай теперь, почему такая деятельность не ведет к достижению. И почему наличие кадра, который 100% времени будет заниматься тестированием, обязательно приведет к гарантированному подтверждению, даже если кроме этого кадра вообще никто продуктом не занимается? Жду.

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

S>>В определении нет речи об обещаниях. Освежи-ка его. Подтверждение соответствия требованиям. Все.

I>А что по твоему есть "гарантированное подтверждение" ?

Ты хочешь сказать, что гарантированное подтверждение это есть обещание? Ну я тогда не понимаю, обещать можно без тестирования. Все что угодно. И заплатить рубль в качестве гарантии, если выяснится, что соответствия требованием не выполнены. Чем тогда это не "гарантированное подтверждение"? И это дешевле, чем держать человека на 100% оклада.

S>>Твой критерий не требует анализа. Он основывался на успехе. Если успех есть — то есть гарантия, нет успеха — значит, он недостижим.


I>Наоборот. Когда ожидания адекватные, разумные, то достижение цели становится возможным. В этом случае при правильном процессе или достигаешь цель, или находишь препятствие, которое необходимо устранить.

Достижение цели становится возможным — это отъезд. Ты говорил о гарантиях достижения.

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


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

У тебя постановка цели = обещание, или я что-то путаю?

S>>Про неизвестное — ты тоже выдумал. "что производимые товары, услуги, выполняемые процессы соответствуют установленным требованиям". Установленным здесь в прошедшем времени. Нет никаких гарантий соответствия неизвестным и неожиданным требованиям. И быть не может.


I>Ок, то есть, сказать нечего.

Я как раз сказал. Тебе ответить нечего.

S>>Когда будут известны требования


I>Ты ведь сказал — что можешь заскриптовать неизвестное. Покажи пример одного единственного фактора, неизвестного на момент скриптования(расширения, дополнения).

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

S>>И часто ты гарантированно подтверждаешь нечто, "о чем ты ни разу не слышал, не видел, не подозревал с начала жизни и будешь ни видеть, ни слышать, ни подозревать вплоть до начала 2020 "


I>Всегда. Я всем говорю, что в софте гарантированно есть неожиданные баги. Чем слабее тестирование, тем выше шанс на них нарваться.


С твоих слов выходит, что контроль качества — бессмысленная затея, т.к. цель недостижима.
Re[98]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 12.11.19 21:22
Оценка:
Здравствуйте, artelk, Вы писали:

A>Главным в этом вопросе является то, что "мир" передается явно и все функции, взаимодействующие с миром, принимают и возвращают его.


putStr не принимает мир и не возвращает его. Она принимает string и возвращает трансформацию мира, не сам мир.

A>Еще полезным было бы как-то на уровне системы типов сделать трюк, запрещающий сохранение текущего состояния мира в переменной с последующим переиспользованием. На сколько понимаю, именно для этого сделали, что "IO a" это тип функций, взаимодействующих с миром, а не тип, хранящий сам мир. "Инстанс" мира глубоко спрятан и недоступен.


Переменных в языке нет, "инстанс" мира — абстрактный тип. Какие еще трюки нужны?
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 и хочу дать пользователям возможность писать такие программы, активность которых можно при желании контролировать удаленно.
Re[103]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 06:56
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Нет, не согласен. См. определение. Принимать IO — еще не грязь.

ARK>>Единственно разумный подход — считать, что это грязь. Это как раз о том, что говорит Sinclair. "Реальную грязь" ты не определишь никак, пишу это в очередной раз. Ты получишь разную картину для одной и той же функции в разных окружениях.
S>В соответствии с единственным разумных подходом (по твоей версии) выходит, что следующая функция в хаскеле грязная, т.к. может принимать IO:
S>
S>id x = x
S>


"Может принимать" и "всегда принимает/возвращает" — разные вещи. Если просто "может" — значит, эта функция ортогональна IO и грязной не является. А вот когда не МОЖЕТ, а ДОЛЖЕН — это уже другое дело.

S>>>Тем более, что putStr не принимает IO.

ARK>>Если в коде нет возможности отделить вызов функции от вызова того, что она возвращает, то эти вещи изоморфны друг другу.
S>Я бы не настаивал на том, что возможности нет, раз такая возможность используется для отделения чистоты от грязи.

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

S>Ну и в конце концов — принимать IO и возвращать — не одно и то же. Или тут тоже проблема?


Увы. Если — и только если — возврат IO ("Action PutStr(string s)") неотделим от вызова грязного action, то он становится семантически полностью эквивалентным как приему-возврату грязного мира ("IO PutStr(IO world, string s)"), так и просто ключевому слову "dirty" в сигнатуре функции ("dirty void PutStr(string s)").

Кстати, продолжая: а если пометить все функции как "dirty", то мы получаем избыточность этого слова — оно становится не нужно, его можно исключить. И — вуаля! — мы получили С.

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

S>"Наша грязная функция" — вот это ты как определил? Ты меня убеди сначала, что она грязная. Хотя нет, давай сначала разберемся с критерием. А то у тебя выходит что id грязный, так нам чистоту putStr не получить.

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

Что же тогда называть "чистой функцией"? Я предлагаю вариант с ДЕКЛАРАЦИЕЙ чистоты (а не тем, что реально происходит при вызове): http://rsdn.org/forum/philosophy/7589812.1
Автор: AlexRK
Дата: 13.11.19

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

ARK>>>Можно считать, что printf тоже возвращает функцию, которая работает с миром. Это маразм, но это вполне укладывается в модель хаскеля.

S>>Результат printf() можно кэшировать?
ARK>А результат вызова putStr можно кэшировать?

Все же жаль, что не удалось узнать, можно ли кэшировать якобы чистую функцию putStr. Было бы интересно послушать.
Re[105]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 07:33
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Все же жаль, что не удалось узнать, можно ли кэшировать якобы чистую функцию putStr. Было бы интересно послушать.


Что мешает попробовать?
Re[106]: Мнение: объектно-ориентированное программирование —
От: AlexRK  
Дата: 13.11.19 07:37
Оценка:
Здравствуйте, samius, Вы писали:

ARK>>Все же жаль, что не удалось узнать, можно ли кэшировать якобы чистую функцию putStr. Было бы интересно послушать.


S>Что мешает попробовать?


Не знаю, как это записать. Можешь подсказать, как закешировать вызов, скажем, putStr("qwerty")? Находясь, разумеется, внутри не-IO функции.

Впрочем, сейчас поковыряю, почему бы нет.
Отредактировано 13.11.2019 7:51 AlexRK . Предыдущая версия .
Re[100]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 07:57
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


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


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


Вау. Других слов нет.

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

ARK>Соответственно, "декларативно чистая" функция — это функция, которая задекларирована как чистая. Во всех известных мне языках под "чистыми" функциями понимаются именно "декларативно чистые".

Во всех известных мне языках (их не так много) вряд ли пользуются ТВОИМ определением чистоты.

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


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


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


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


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

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

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

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

Если он не часть определения, почему ты опираешься на этот перечень?

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

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

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


Немного не так. Я смотрю на контракт, чист ли он? Если синус отличается от своего контракта, то это проблема частной реализации синуса, а не контракта. Если это так — возьму другой.

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


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


Ну как, ты же судишь по виртуальной машине!

ARK>>>Оно не гадит в момент связывания. А гадит, когда "внешний вычислитель" это запустит. В точности, как в хаскеле.

S>>Передает ли внешний вычислитель при этом управление printf-у? Если да, то грязь появляется до или после возврата управления?

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

А в какой момент action получит строку для вывода, сгенерированную в рантайме?

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


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

Я смотрю, есть ли там вообще пространство для грязи на уровне контракта, потом дополнительно проверяю вызовы подозрительных функций. В State достаточно посмотреть на вызовы IO внутри. Или unsafe. Ну а зачем, главное? Я прекрасно знаю, как устроен State. Сам его писал. Воткнуть в него вывод можно, но объясни, зачем?

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


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

Интересно, что мешает пользователям контролировать активность без нового компилятора? Но ты, видимо, не только компилятор, а еще и все исходники хочешь переписать. Ну ладно. Успехов.
Re[104]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 08:06
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


S>>>>Нет, не согласен. См. определение. Принимать IO — еще не грязь.

ARK>>>Единственно разумный подход — считать, что это грязь.
S>>В соответствии с единственным разумных подходом (по твоей версии) выходит, что следующая функция в хаскеле грязная, т.к. может принимать IO:
S>>
S>>id x = x
S>>


ARK>"Может принимать" и "всегда принимает/возвращает" — разные вещи. Если просто "может" — значит, эта функция ортогональна IO и грязной не является. А вот когда не МОЖЕТ, а ДОЛЖЕН — это уже другое дело.

Это юлеж. Постом назад альтернатив и ортогональностей не было, был единственно разумный подход!

S>>>>Тем более, что putStr не принимает IO.

ARK>>>Если в коде нет возможности отделить вызов функции от вызова того, что она возвращает, то эти вещи изоморфны друг другу.
S>>Я бы не настаивал на том, что возможности нет, раз такая возможность используется для отделения чистоты от грязи.

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

Т.е. все, кто кэширует IO, делают это лишь из-за богатого воображения?

S>>Ну и в конце концов — принимать IO и возвращать — не одно и то же. Или тут тоже проблема?


ARK>Увы. Если — и только если — возврат IO ("Action PutStr(string s)") неотделим от вызова грязного action, то он становится семантически полностью эквивалентным как приему-возврату грязного мира ("IO PutStr(IO world, string s)"), так и просто ключевому слову "dirty" в сигнатуре функции ("dirty void PutStr(string s)").

Ну а почему неотделим-то?

ARK>Кстати, продолжая: а если пометить все функции как "dirty", то мы получаем избыточность этого слова — оно становится не нужно, его можно исключить. И — вуаля! — мы получили С.


S>>"Наша грязная функция" — вот это ты как определил? Ты меня убеди сначала, что она грязная. Хотя нет, давай сначала разберемся с критерием. А то у тебя выходит что id грязный, так нам чистоту putStr не получить.


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

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

ARK>Что же тогда называть "чистой функцией"? Я предлагаю вариант с ДЕКЛАРАЦИЕЙ чистоты (а не тем, что реально происходит при вызове): http://rsdn.org/forum/philosophy/7589812.1
Автор: AlexRK
Дата: 13.11.19

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

Видишь лист бумаги? Думаешь, он белый? А я возьму красный фильтр и докажу что он красный. Именно это ты предлагаешь с фальсификацией окружения. Смысла в этом 0.
Re[107]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.19 08:07
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


ARK>>>Все же жаль, что не удалось узнать, можно ли кэшировать якобы чистую функцию putStr. Было бы интересно послушать.


S>>Что мешает попробовать?


ARK>Не знаю, как это записать. Можешь подсказать, как закешировать вызов, скажем, putStr("qwerty")? Находясь, разумеется, внутри не-IO функции.


putStrLn1 = putStrLn "querty"

main = do
  putStrLn1
  putStrLn1


ARK>Впрочем, сейчас поковыряю, почему бы нет.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.