Информация об изменениях

Сообщение Re[11]: Ввод-вывод и чистые функции от 30.01.2017 8:09

Изменено 30.01.2017 8:21 AlexRK

Re[11]: Ввод-вывод и чистые функции
Здравствуйте, alex_public, Вы писали:

_>Она грязная с точки зрения отсутствия соответствующих атрибутов. Но сама то по построению очевидно чистая. Так что соответственно если передать в неё чистые аргументы, то и вся конструкция окажется чистой (опять же по построению, а не атрибутам типа).


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

ARK>>Таким образом, получаем два мапа — один чистый, один грязный. Кривовато...

_>Ну как бы а какие ещё варианты? ) В других языках и такого нет. )))

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

_>Вообще я бы сделал одно исправление в механике работы D в этом смысле. Сейчас (во всяком случае на тот момент, когда я игрался с D — может за пару последних лет что-то и поменялось) атрибут pure устанавливается программистов и потом проверяется компилятором (если функция не удовлетворяет нужным условиям, то получаем ошибку компиляции). А бы предложил сделать наоборот: чтобы компилятор сам проверял все функции на предмет чистоты и в случае удовлетворения требований сам проставлял бы этот атрибут.


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

_>Если сделать такое изменение, то можно и расставить требование на pure во многих местах библиотеки. Потому что при таком раскладе оно не будет напрягать классических "императивных" программистов, которые не в курсе ни про какие pure и не собираются их использовать в своём коде.


Вот тут не очень понял. Если pure уже проставлено, то чего с ним еще можно сделать? Или имеется в виду, что модификатор "pure" может быть при необходимости отменен компилятором, если он видит возможность нечистого вызова? Тогда опять же с такого модификатора нет особого толка, если он не дает гарантий...

В общем, по большому счету есть немного вариантов:
1) "железобетонное" pure — приходим к необходимости дублировать некоторые функции в чистом и грязном виде;
2) "мягкое" pure — необходимо учитывать весь контекст вызова, чтобы точно знать, pure оно или нет;
3) оверинженернутый подход а-ля Хаскель — приводит к распространению по коду "лифтингов";
4) вообще никакого контроля а-ля C/C++.

Криво — всё.

Лично мне из всех зол пока почему-то больше нравится вариант 1.
Re[11]: Ввод-вывод и чистые функции
Здравствуйте, alex_public, Вы писали:

_>Она грязная с точки зрения отсутствия соответствующих атрибутов. Но сама то по построению очевидно чистая. Так что соответственно если передать в неё чистые аргументы, то и вся конструкция окажется чистой (опять же по построению, а не атрибутам типа).


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

ARK>>Таким образом, получаем два мапа — один чистый, один грязный. Кривовато...

_>Ну как бы а какие ещё варианты? ) В других языках и такого нет. )))

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

_>Вообще я бы сделал одно исправление в механике работы D в этом смысле. Сейчас (во всяком случае на тот момент, когда я игрался с D — может за пару последних лет что-то и поменялось) атрибут pure устанавливается программистов и потом проверяется компилятором (если функция не удовлетворяет нужным условиям, то получаем ошибку компиляции). А бы предложил сделать наоборот: чтобы компилятор сам проверял все функции на предмет чистоты и в случае удовлетворения требований сам проставлял бы этот атрибут.


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

_>Если сделать такое изменение, то можно и расставить требование на pure во многих местах библиотеки. Потому что при таком раскладе оно не будет напрягать классических "императивных" программистов, которые не в курсе ни про какие pure и не собираются их использовать в своём коде.


Вот тут не очень понял. Если pure уже проставлено, то чего с ним еще можно сделать? Или имеется в виду, что модификатор "pure" может быть при необходимости отменен компилятором, если он видит возможность нечистого вызова? Тогда опять же с такого модификатора нет особого толка, если он не дает гарантий...

UPD. А, кажется понял. Вы имеете в виду, что pure будет гарантировать именно ту самую "чистоту по построению", но не чистоту самого вызова. В принципе да, это неплохо.



В общем, по большому счету есть немного вариантов:
1) "железобетонное" pure — приходим к необходимости дублировать некоторые функции в чистом и грязном виде;
2) "мягкое" pure — необходимо учитывать весь контекст вызова, чтобы точно знать, pure оно или нет;
3) оверинженернутый подход а-ля Хаскель — приводит к распространению по коду "лифтингов";
4) вообще никакого контроля а-ля C/C++.

Криво — всё.

Лично мне из всех зол пока почему-то больше нравится вариант 1. Хотя, после некоторых размышлений, вариант 2 может быть даже и лучше.