Re[7]: Ленивые языки - за и против
От: thesz Россия http://thesz.livejournal.com
Дата: 17.12.08 13:48
Оценка:
VD>Ну, а по делу скажу только то, что не так много на свете людей у которых мыслительный процесс расходится с ходом вычислений.

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

VD>Скорее у большинства возникают проблемы когда вычислительный процесс вдруг начинает жить своей жизнью.

VD>Потом если бы ленивость была бесплатной (в данном случае речь не о производительности), а так за отложенность вычислений прихдится платить тем, что приходится повсеместно возиться с головоломными монадами. А ведь голова не компьютер. Она уровень косвенности больше 2 переваривает с трудом.

http://mskhug.ru/wiki/monadicparsers — самое сложное, что тебя может ожидать.

Ничего головоломного.

Это опыт 10 лет использования Хаскеля.

T>>Например, я часто применяю операции наподобие (head:tail) = someListThatMayBeEmpty и потом беру результаты этого опасного сравнения с образцом исходя из других критериев, когда, например, этот список точно не может быть пуст.

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

Последний вопрос совершенно бессмыслен.

Я могу сравнивать только с известными мне и при этом существующими.

Теоретический аргумент, точнее, два аргумента: лямбда-исчисление самый простой метод вычислений (всего одна операция упрощения) и нормальный порядок упрощения (ленивость) самый полный порядок упрощений. В ленивом порядке вычислений вычисляется всё то, что может быть теоретически вычислено, в отличии от других способов упрощений.

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

При этом для ленивого ЛИ есть отличная система типов с big step семантикой — Hindley-Milner с алгебраическими типами, ага.

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

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

T>>В результате мой код полон ленивых сравнений с образцом и, соответственно, он сильно завязан на ленивые вычисления.

VD>И в результате главным достоинством твоего кода становится, то что тебя прёт он него. А то что другим его не понять только потешит твое самолюбие...

Главным достоинством моего кода является то, что его рабочий вариант (решающий проблему) я получаю, в среднем, чуток быстрее других.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[6]: Ленивые языки - за и против
От: Gaperton http://gaperton.livejournal.com
Дата: 17.12.08 14:25
Оценка:
Здравствуйте, lomeo, Вы писали:

G>>>>Тезис: никакого значимого выигрыша от ленивости везде по умолчанию нет.

G>>>>Опровергать тезис по существу будешь? Я бы хотел наглядный и убедительный контрпример, лишенный эмоций и шелухи.

L>>>Например, при ленивости по умолчанию код более лаконичен. Это считается выигрышем?


G>>Возможно, если это оправдывает приведенные недостатки. Пример, пожалуйста, для иллюстрации вашей мысли.


L>Ну! Ты говорил, что вообще "никакого значимого выигрыша от ленивости везде по умолчанию нет." Я показал то, что считаю выигрышем (для ясности — мы же под этим словом понимаем преимущество?). А оправдывает он или нет приведенные недостатки зависит от задачи, полагаю. Может в некоторых задачах вообще этих недостатков нет или они неважны.


Да. И продолжаю так думать и говорить, так как ты ничего не делаешь, чтобы меня разубедить. Я, что характерно, не прочь разубедится в этом, увидев контрпример. Почему ты его не приводишь, это ж должно быть так элементарно просто и очевидно, нет? Стесняться не надо, все свои.
Re[7]: Ленивые языки - за и против
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.12.08 14:29
Оценка:
Здравствуйте, Gaperton, Вы писали:

L>>Ну! Ты говорил, что вообще "никакого значимого выигрыша от ленивости везде по умолчанию нет." Я показал то, что считаю выигрышем (для ясности — мы же под этим словом понимаем преимущество?). А оправдывает он или нет приведенные недостатки зависит от задачи, полагаю. Может в некоторых задачах вообще этих недостатков нет или они неважны.


G>Да. И продолжаю так думать и говорить, так как ты ничего не делаешь, чтобы меня разубедить. Я, что характерно, не прочь разубедится в этом, увидев контрпример. Почему ты его не приводишь, это ж должно быть так элементарно просто и очевидно, нет? Стесняться не надо, все свои.


У нас какой то разговор странный получается. Пример чего я должен привести? И в чём я тебя должен разубедить?
Ты хочешь, чтобы я показал, что ленивый код лаконичен? Или что лаконичность — это преимущество, я не очень понимаю, что от меня требуется.
Re[7]: Ленивые языки - за и против
От: thesz Россия http://thesz.livejournal.com
Дата: 17.12.08 14:54
Оценка: 1 (1)
L>>2. Лёгкое отделение генерации от выборки. В коде просто видно — вот тут мы создаём структуру данных, а тут обрабатываем её. При ленивости по умолчанию не нужно смешивать эти два отдельных по сути этапа, чтобы создать только то, что будет обработано. Учитывая, что каждый из этих этапов сам может разбиваться на подэтапы, порождающие структуры (map f . map g . map h) — ленивость играет большую роль.
VD>ОК, принимается. С оговоркой. Ленивые списки (или их аналоги) сейчас есть практически везде. И функции склеивать можно даже в C#. А уж для разных ОКамлов и Немерлов это самая, что ни на есть банальщина.

I believe it when I see it.

Как минимум для OCaml ты не прав.

Rewrite rules для OCaml нет. Более того, deforestation (которая склейка функций) для строгих языков может изменить семантику программы. Без этой оптимизации программа не будет работать, а с оптимизацией — будет. Поэтому такие преобразования никто для ML семейства не пишет (за исключением Lazy ML).

L>>3. Соответственно подобное разделение позволяет выписывать комбинаторы и использовать их отдельно. Повторное использование, что тоже показатель лаконичности.

VD>Не видел подобных проблем в не ленивых языках.

Какие комбинаторы ты на них писал?

L>>4. eDSL без макросов — следствие ленивости (одна из причин)!

VD>Ой. Только не на до про ДСЛ-и. Ладно? Есть разные пути их создания.
VD>Вообще, надо бы стравить Лиспаря и Хаскелиста... и поглядеть на получившийся флэйм.

Лисперы быстро обижаются и отваливаются. Проходили. Они же как дети.

L>>5. Можно ещё много чего дописать — всё это связано с тем, что бета-редукция при ленивости не ограничивается никаким порядком.

VD>Можно. Но все это треп и понты. А по жизни код есть код. Ленивость при обработке списков иногда полезно. Но ее не трудно достичь и в не ленивом языке. А ленивость в обычном коде скорее создает проблемы, чем их решает.

Лично для меня сейчас написание последовательного кода на Java является проблемой.

Там надо думать, что за чем идёт.

И переменные можно переписать, а значит, испортить.

VD>А вот, то что код нельзя тупо превратить в машинные команды, а надо заниматься разными бета-редукциями — это проблема. Сколько слов сказано о том, что в Хаскеле все можно соптимизировать? И где эти оптимизации?


О!

Я так и знал.

Всё сведётся к банальной оптимизации.

Тебе сперва проблему надо решить, а потом оптимизировать решение.

L>>1. В цепочке map/filter/fold важно ленивы они или нет. Неленивые — неэффективны (или вообще невозможны для бесконечных списков). Поэтому так популярны итераторы.

VD>Чушь полнейшая. Во-первых, только у теоретиков везде возникают бесконечные списки. У всех остальных есть списко и его надо обработать. 99% программистов их до сих пор for-ами на Cxx обрабатывают. Ну, и если вдруг появляется нужда в ленивых map/filter/fold, то нет проблем их использовать. Как, по-твоему, работают Select, Where, Aggregate в LINQ?

Это когда появилось-то? Год назад?

А почему появилось-то?

Ну, да ладно.

L>>2. Про медленную ленивую обработку списков — это утверждение тоже требует доказательства

VD>Скорее обратное доказательства. Если обработка не переписана в код аналогичный for, то ее скорость по любому оставляет желать лучшего. А добиться отложенности вычислений на современных процессорах без доп.затрат нельзя в принципе.

Вот, смотри: http://thesz.mskhug.ru/browser/hiersort/core/S.hs

Это ядро моей самопальной системы моделирования аппаратуры.

Оно пишется за 15 минут и сразу готово к использованию.

Такое же дело на сообщениях для Эрланга товарищ Gaperton продумывал в районе недели, не меньше.

L>>Никто не спорит. Strictness тоже легко достигается в ленивых языках.

VD>Может быть. Только я таких не знаю. Идею применять монады для того чтобы сделать код последовательным нельзя не только назвать простой, но и здоровой. Это же надо так извращаться чтобы достичь то, что и так есть?

Монады-то здесь причём?

Монады к strictness отношения не имеют.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[6]: Ленивые языки - за и против
От: Gaperton http://gaperton.livejournal.com
Дата: 17.12.08 21:54
Оценка:
Здравствуйте, awson, Вы писали:

G>>Использование или не использование о3 не приводит к таким результатам, как мемори лик в программе из-за невычисленной цепочки. Эффект от о3 в целом презсказуем. В этом разница.

G>>Для встраиваемой железки или высоконагруженного сервера такие свойства, как расход памяти, должны быть доказуемы. Так дешевле. В этом смысле — да, до сих пор следим за динамической памятью.
G>>Let is crash тут не причем. Твое мнение о серьезности или не серьезности данной пробемы я приму во внимание, когда ты напишешь на Хаскеле хотя бы один нетривиальный высоконагруженный сервер. А пока ты этого не сделал, извини — я хочу доказательств, или хотя бы обоснований.

A>Все так. Проблемы с ленивыми вычислениями есть и они объективны. НО. Как показывает опыт, люди научаются с ними работать и справляться. Т.о., речь не идет об абстрактных вопросах — что лучше — ленивые или энергичные вычисления, а о вполне прагматичных, типа — какие инструменты у нас под рукой?


Я ничего не говорил про проблемы с ленивыми вычислениями. Я говорил про проблемы, возникающие при тотальной ленивости по умолчанию, когда она возникает везде, а не там где ты хочешь. И что строгость по умолчанию с lazy annotation (а не ленивость с strictness annotation) — самый простой и практичный на мой взгляд способ решения этих проблем, при сохранении выгоды от ленивости.

Вы когда-нибудь научитесь читать, что вам пишут?

A>Любая из рапространенных платформ имеет свои недостатки и преимущества. Когда я обсуждал с заказчиком одного небольшого проекта стоит ли (и почему я собираюсь) в нем использовать Хаскелл — я честно написал, что с ним проблем — вагон и маленькая тележка, но в нашем конкретном случае его выразительность и мощь — перевешивают.


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

A>Основные проблемы здесь — недостаток опыта использования в *реальных* приложениях.


Раз нет такого опыта, то ты не можешь утверждать, что перевешивает. Ты просто не можешь этого знать.

A>Иными словами, я агитирую за Хаскелл не потому, что он во всех отношениях безупречен, а потому, что для очень очень широкого круга задач (высоконагруженных серверов тож) это — оптимальный выбор.


Меня бесполезно агитировать. И я не считаю Хаскель оптимальным выбором для очень широкого круга задач. И в особенности — высоконагруженных серверов. Как я сказал — верования меня не интересуют, меня интересуют факты, и рассуждения.
Re[8]: Ленивые языки - за и против
От: Gaperton http://gaperton.livejournal.com
Дата: 17.12.08 22:01
Оценка:
Здравствуйте, lomeo, Вы писали:

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


L>>>Ну! Ты говорил, что вообще "никакого значимого выигрыша от ленивости везде по умолчанию нет." Я показал то, что считаю выигрышем (для ясности — мы же под этим словом понимаем преимущество?). А оправдывает он или нет приведенные недостатки зависит от задачи, полагаю. Может в некоторых задачах вообще этих недостатков нет или они неважны.


G>>Да. И продолжаю так думать и говорить, так как ты ничего не делаешь, чтобы меня разубедить. Я, что характерно, не прочь разубедится в этом, увидев контрпример. Почему ты его не приводишь, это ж должно быть так элементарно просто и очевидно, нет? Стесняться не надо, все свои.


L>У нас какой то разговор странный получается. Пример чего я должен привести? И в чём я тебя должен разубедить?


Советую внимательно перечитать пост, на который ты отвечал. Надо же понимать, на что отвечаешь, а то будет получаться странный разговор.
http://rsdn.ru/forum/message/3215352.1.aspx
Автор: Gaperton
Дата: 15.12.08

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

Опровергать тезис по существу будешь? Я бы хотел наглядный и убедительный контрпример, лишенный эмоций и шелухи.


L>Ты хочешь, чтобы я показал, что ленивый код лаконичен? Или что лаконичность — это преимущество, я не очень понимаю, что от меня требуется.


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

Я хоть от кого-нибудь из вас услышу ответ на свой вопрос, в конце концов? Уже десяток постов ни о чем в форум легло.
Re[6]: Ленивые языки - за и против
От: Gaperton http://gaperton.livejournal.com
Дата: 17.12.08 22:06
Оценка: +1 :)
Здравствуйте, thesz, Вы писали:

L>>>Например, при ленивости по умолчанию код более лаконичен. Это считается выигрышем?

VD>>Это утверждение требует доказательства. Пока что такие доказательства дальше разных фибоначей не пошли.
VD>>Мое мнение — ленивость нужна только при обработке списков, да и то не все время. В большинстве случаев совершенно все равно лениво обрабатывается список или нет. А вот быстро это делается или медленно зачастую важно. Так что для реальной жизни важно чтобы map, fold, filter, forall и т.п. не проигрывали по скорости аналогичным циклам в компилируемых языках. А ленивы он или нет дело десятое.

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


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

T>Например, я часто применяю операции наподобие (head:tail) = someListThatMayBeEmpty и потом беру результаты этого опасного сравнения с образцом исходя из других критериев, когда, например, этот список точно не может быть пуст.


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

T>В результате мой код полон ленивых сравнений с образцом и, соответственно, он сильно завязан на ленивые вычисления.


Я так понимаю, ты сторонник обфускации, потому что не любишь, когда чужие люби читают твои программы.
Re[6]: Ленивые языки - за и против
От: Gaperton http://gaperton.livejournal.com
Дата: 17.12.08 22:08
Оценка:
Здравствуйте, lomeo, Вы писали:

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


L>>>Например, при ленивости по умолчанию код более лаконичен. Это считается выигрышем?


VD>>Это утверждение требует доказательства. Пока что такие доказательства дальше разных фибоначей не пошли.


L>Для начала классика: Why FP matters. Must read.


L>Теперь обоснования

...
L>Никто не спорит. Strictness тоже легко достигается в ленивых языках.

И какое из этих обоснований говорит в пользу того, что все должно быть по умолчанию ленивым, а не строгим?
Re[6]: Ленивые языки - за и против
От: Gaperton http://gaperton.livejournal.com
Дата: 17.12.08 22:38
Оценка:
Здравствуйте, thesz, Вы писали:

T>>>Full throttle emotions

G>>А вот это ты зря. Сам понимаешь, если ты не прав, то зачем волноваться? Это как то по детски. Ну а теперь, допустим, что ты прав. Ну, тогда тем более непонятно, что ты волнуешься.

T>Как ты сам понимаешь, мне может просто нравится волноваться в таких ситуациях.


T>Грех не воспользоваться возможностью.


T>>>Ты говоришь с высоты своего не очень большого опыта. Ну сколько ты написал на ленивом ФЯ? Сотни три строчек, наверное. А сколько на строгом? Да примерно столько же. А писал ли ты на любом из них скорость получения первого результата? Нет, не писал.

G>>Если бы мой "не очень большой опыт" исчерпывался строками кода на ФЯ, то я бы немедленно посыпал голову пеплом. Однако, мой опыт коммерческой разработки не меньше твоего. А если говорить о высоконагруженных надежных серверных приложениях — то он существенно превышает твой опыт, Сергей. Ты ведь на поддержке софтины, написанной не тобой, вообще никогда не сидел, не так ли? Предлагаю замять для ясности, и тему не развивать.

T>Как так? Я же неоднократно тебе рассказывал про программу с глобальным int i.


T>В ПСиТ я вообще исправлял ошибки за всей командой, без малого. В высоконадёжной системе, тоже связанной с финансами.


T>Так что я не вижу причин, по которым надо это заминать.


Ну, если бы ты видел причины, то не заставил бы меня напоминать тебе, что:
1) ни одного коммерческого ПО, которое дошло бы до продакшн, и которому требуется поддержка, ты на Хаскеле не написал.
2) Твой опыт исключается двумя темами, из которых одну вы с potan не доделали, а вторая — это архитектурные прототипы харда, который ты делал в одиночку на выброс.
3) Ни одна из этих программ не работала на пределе возможностей оборудования, и не была интерактивной.

Это не засчитывается за значимый опыт разработки. Это так называемое "экспериментальное программирование".

T>Да и носки у меня стоят лучше. Просто потому, что я старше.


Старше, значит — соображаешь медленнее :Р.

T>>>Да ты даже Вадлера не читал толком. У него про пользу ленивых вычислений отдельная статья.

G>>Ты читал Вадлера толком — так почему тебе проще обсуждать мою личность, а не объяснить мне Вадлера? Тем более, что я с тобой разговариваю, и тебя об этом прошу. В чем проблема? Вот ты Вадлера толком понял — и что, ты не в состоянии это просто и доходчиво объяснить другим?

T>Ты как-то странно об этом просишь.


T>Буквально, год назад объяснил тебе всё, что сейчас пытаюсь объяснить. Вроде, ты сказал, что понял. И вот снова вынужден это делать.


Ты так хорошо объясняешь, что я слабо понимаю, что ты мне вообще хочешь сейчас объяснить.

T>Видимо, то было лично, вне просторов RSDN, а это "не считается".


Видимо, сейчас ты просто придумываешь те события, которых не было.

T>И как ты просто обязан знать, "знать и применять" не означает "способен просто и доходчиво объяснить другим".


Ну да, это на самом деле так. Способность научить — третий, высший уровень понимания предмета. Первый — повторение, второй — умение применять.

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

T>Да и место для объяснений здесь так себе. Некая нехорошая аура.


Так. Вот не надо сейчас на дурную ауру все списывать — типа место предрасполагает к флейму!

Нет уж. Взялся за гуж — полезай в корзину.

T>>>Как контролируются задержки в ленивом ФЯ, я уже рассказывал. Как и всё в таких ФЯ, они контролируются высокомодульно — есть генератор, есть потребитель. Потребитель потребляет создаваемое, пока не сочтёт, что упёрся или не завершится время на решение.

G>>Я тебя просил привести пример. Пример будет?

T>Я не смогу написать что-то, отличное от абзаца выше.


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

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

T>Поэтому — почему это не контрпример?


"Контпример" происходит от слова "пример". Не вижу в этом никакого намека на пример.

T>>>Неконтролируемый расход памяти — это да, проблема. Но она менее серьёзна, чем её пытаются представить. Let it crash никто не отменял.

G>>Let is crash тут не причем. Твое мнение о серьезности или не серьезности данной пробемы я приму во внимание, когда ты напишешь на Хаскеле хотя бы один нетривиальный высоконагруженный сервер. А пока ты этого не сделал, извини — я хочу доказательств, или хотя бы обоснований.

T>Я повторю свой вопрос: О чем же мы тогда спорим?


T>Какой тезис я доказываю, с твоей точки зрения?


Начал ты с того, что обвинил меня в преждевременной оптимизации.
Потом я сказал, что считаю lazy annotation более продуктивной, чем strictness annotation. Привел обоснование. И попросил тебя по правилам это опровергнуть.
В ответ ты возмутился, грязно не по делу наехал, и в конце конов забыл, о чем споришь, и стал жаловаться на дурную карму этого места.

Примерно такая хронология событий. А-аставайтесь с нами.
Re[7]: Ленивые языки - за и против
От: awson  
Дата: 17.12.08 23:54
Оценка:
Здравствуйте, Gaperton, Вы писали:

A>>Все так. Проблемы с ленивыми вычислениями есть и они объективны. НО. Как показывает опыт, люди научаются с ними работать и справляться. Т.о., речь не идет об абстрактных вопросах — что лучше — ленивые или энергичные вычисления, а о вполне прагматичных, типа — какие инструменты у нас под рукой?

G>Я ничего не говорил про проблемы с ленивыми вычислениями. Я говорил про проблемы, возникающие при тотальной ленивости по умолчанию, когда она возникает везде, а не там где ты хочешь. И что строгость по умолчанию с lazy annotation (а не ленивость с strictness annotation) — самый простой и практичный на мой взгляд способ решения этих проблем, при сохранении выгоды от ленивости.
Разговоры, что лучше — в лоб или по лбу, с моей точки зрения, совершенно пустые. Содержательно, проблема именно в семантике вычислений, а не в том, куда двигать "умолчание". В том же Хаскелле strictness annotation можно расставить отнюдь не везде и отнюдь не всякое вычисление сделать строгим. Я не знаю, что конкретно Вы имеете в виду (если вообще) под "строгостью по умолчанию с lazy annotation", но предполагаю, что с этим будет еще хуже.

G>Вы когда-нибудь научитесь читать, что вам пишут?

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

A>>Любая из рапространенных платформ имеет свои недостатки и преимущества. Когда я обсуждал с заказчиком одного небольшого проекта стоит ли (и почему я собираюсь) в нем использовать Хаскелл — я честно написал, что с ним проблем — вагон и маленькая тележка, но в нашем конкретном случае его выразительность и мощь — перевешивают.

G>Покажи мне ход твоих рассуждений, и я, может быть, с ним соглашусь. А может нет. Пока я не вижу никаких рассуждений, с чем можно было соглашаться или не соглашаться. Во что ты веришь, мне не интересно — это абсолютно практически бесполезно для меня, и мне это все равно.
A>>Иными словами, я агитирую за Хаскелл не потому, что он во всех отношениях безупречен, а потому, что для очень очень широкого круга задач (высоконагруженных серверов тож) это — оптимальный выбор.
G>Меня бесполезно агитировать. И я не считаю Хаскель оптимальным выбором для очень широкого круга задач. И в особенности — высоконагруженных серверов. Как я сказал — верования меня не интересуют, меня интересуют факты, и рассуждения.
Вы, боюсь, недостаточно знаете Хаскелл, чтобы такие обсуждения имели смысл.
Re[8]: Ленивые языки - за и против
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 18.12.08 02:30
Оценка: +1
Здравствуйте, lomeo, Вы писали:

L>б) А что на Камлах и Немерлях пишут — map f . map g . map h?


Пишут, пишут! Просто не List.map (который создает новый список), а, например, Enum.map (который ленивый).

Например, полный исходник решения задачки 42 из Project Euler:
open ExtString;;
open ExtList;;

let (>>) f g = g f;;
let flip f x y = f y x;;
let wordvalue s = String.enum s >> Enum.map (fun c->int_of_char c - 64) >> Enum.fold (+) 0;;
let triangs = Enum.init 20 (fun n-> (n+1)*(n+2)/2) >> List.of_enum;;
let istriang s = if List.mem (wordvalue s) triangs then 1 else 0;;

"words.txt" >> Std.input_file >> flip String.nsplit "," >> List.enum >>
Enum.map (fun s->String.sub s 1 (String.length s - 2)) >> Enum.map istriang >> Enum.fold (+) 0 >> print_int;;
Re[7]: Ленивые языки - за и против
От: yumi  
Дата: 18.12.08 03:32
Оценка: 6 (1) :)))
Здравствуйте, VladD2, Вы писали:

L>>Для начала классика: Why FP matters. Must read.

VD>Спасибо, религиозным чтивом не увлекаюсь. В свое время не осилил даже Майн Камф.

Может наоборот, религия не позволяет прочитать? Или лень? Если второе, то да, ленивость по умолчанию это плохо

VD>Это мы отвергаем сразу по двум причинам:

VD>1. Ленивые структуры данных доступны и не ленивых по умолчанию языках.

+1.

VD>2. Ни фига они ни не дает грандиозного выигрыша в общем случае. Большую часть времени программист возится со списками или массивами.


И именно поэтому, это дает выигрыш, кумулятивный эффект видите ли.

L>>4. eDSL без макросов — следствие ленивости (одна из причин)!

VD>Ой. Только не на до про ДСЛ-и. Ладно? Есть разные пути их создания.

Я вижу два пути создания eDSL, это путь Лиспа (который кстати и использует Немерле) путем манипуляции АСТ. А есть второй путь, путь Хаскеля, он вообще я бы сказал ортогонален пути Лиспа. Можно конечно порассуждать на тему, плюсы и минусы обоих подходов, но что-то неохота

VD>Вообще, надо бы стравить Лиспаря и Хаскелиста... и поглядеть на получившийся флэйм.


Я бы поставил на Лиспаря, обычно от Хаскеллистов так и прет непонятным фанатизмом. В этом плане, Лисп все же более приземленный язык близкий к real-world.

VD>Можно. Но все это треп и понты. А по жизни код есть код. Ленивость при обработке списков иногда полезно. Но ее не трудно достичь и в не ленивом языке. А ленивость в обычном коде скорее создает проблемы, чем их решает.


+1.

VD>А вот, то что код нельзя тупо превратить в машинные команды, а надо заниматься разными бета-редукциями — это проблема. Сколько слов сказано о том, что в Хаскеле все можно соптимизировать? И где эти оптимизации?


Бедные Хаскеллисты, прям их жалко стало (пускаю скупую мужскую слезу) занимаются разными нехорошими и непонятными бета-редукциями А тем временем в деревне вилла-бадже дотнетисты и джависты не занимаются не понятными бета-редукциями, их код весело превращается сразу в машинные команды.

VD>Чушь полнейшая. Во-первых, только у теоретиков везде возникают бесконечные списки. У всех остальных есть списко и его надо обработать. 99% программистов их до сих пор for-ами на Cxx обрабатывают. Ну, и если вдруг появляется нужда в ленивых map/filter/fold, то нет проблем их использовать. Как, по-твоему, работают Select, Where, Aggregate в LINQ?


Бесконечный список, это абстракция. Она возникает не только у теоретиков, но и у практиков. Как и всякая любая абстракция, она призвана упростить понимание и использование такой сущности как список. В этом нет ничего плохого, как и в том, что 99% лет десять-двадцать назад писали на голом ассемблере без for-ов.

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


Оргазмы лучше получать от других занятий Нет, я имею ввиду, что есть люди получающие оргазм от новых крутых, концептуально чистых вещей и есть люди получающие оргазм от успешно завершенного проекта. Правда оргазмы всякие разные полезны, и те и те, гораздо хуже вообще их не получать
Lisp is not dead. It’s just the URL that has changed:
http://clojure.org
Re[8]: Ленивые языки - за и против
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.08 05:58
Оценка:
Здравствуйте, lomeo, Вы писали:

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


VD>>Спасибо, религиозным чтивом не увлекаюсь. В свое время не осилил даже Майн Камф.


L>Это не религиозное чтиво. В этой статье показывается на примерах где и как рулит ленивость. Мне бы не пришлось писать предыдущий, да и этот пост, если бы ты просто прочитал эту статью.


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

Возьмем пример из этой статьи.

Since the Newton-Raphson algorithm computes a sequence of approximations it is natural to represent this explicitly in the program by a list of approximations.
Each approximation is derived from the previous one by the function

next N x = (x + N/x) / 2

so (next N) is the function mapping one approximation onto the next. Calling this function f, the sequence of approximations is
[a0, f a0, f(f a0), f(f(f a0)), ..]

We can define a function to compute this:
repeat f a = cons a (repeat f (f a))

so that the list of approximations can be computed by
repeat (next N) a0

Удобно ли для решения этой конкретной задачи применять ленивую функцию "repeat"?
Наверно — да.
Нужно ли для ее создания, чтобы язык на котором ее пишут был ленивым по умолчанию?
Точно — нет.
Вот тебе пример такой функции на Nemerle (его не сложно написать и на C# 2.0, но мне проще писать на Немерле):
using System.Console;
using System.Collections.Generic;

module Program
{
  Repeat[T](n : T, f : T -> T) : IEnumerable[T]
  {
    def loop(n)
    {
      yield n;
      loop(f(n))      
    }
    
    loop(n)
  }
  
  Main() : void
  {
    def res = Repeat(1, x => x + 1); // Для наглядности применяем простой инкремент 
    WriteLine("Мы получили бесконечный список :)");
    foreach (x in res)
      WriteLine(x);
  }


Можно конечно возразить, что писать функции аналогичные Repeat проще на ленивом языке, но ёлы-палы, кто же будет их писать постоянно? Нам реально нужны Map и Fiter. Ну, на крайняк напишем еще пару более специализированных функций. А скажем функции вроде Fold вообще бессмысленно делать ленивыми. Нам же ведь нужен результат, а не процесс!

VD>>Это мы отвергаем сразу по двум причинам:

VD>>1. Ленивые структуры данных доступны и не ленивых по умолчанию языках.
VD>>2. Ни фига они ни не дает грандиозного выигрыша в общем случае. Большую часть времени программист возится со списками или массивами.

L>1. Да, но записываются они не так лаконично, как в ленивых. А мы же о лаконичности, как преимуществе ленивости, не так ли?


На фи не нужна экономия 2 символов раз в пол года. В тома же Немерле мне нужно дописать lazy в паре мест, чтобы получить ленивую структуру. Но на практике я, написав на том же Немерле пару мег кода, не создал ни одной (!) ленивой структуры данных. Ну, не нужны они мне.
Может быть конечно, что мой мозг так устроен. Но мне кажется дело в другом (о чем я уже говорл). Дело в том, что:
1. Я могу получать ленивость и другими средствами.
2. Ленивость реально полезна только для списков (деревья приравниваем к ним).
3. Большинство реальных задач не требует ленивости и не страдает от того, что ее не использовали.

L>2. Про грандиозный я не говорил. Я говорил про заметный. Большую часть времени программист возится со списками и массивами — это что? Опровержение того, что ленивый код лаконичен?


Нет. Но и не доказательство обратного.

L>Если да — разверни. Если нет — поясни, зачем ты это написал.


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

Ну, а для обработки списков в ленивой манере можно сделать библиотеку содержащую набор ленивых функций. Вот тот же LINQ отличный пример такого подхода. Столь удобной библиотеки я не видел ни в одном самом ленивом языке. Хотя казалось бы Шарпу (на котором написаны библиотеки LINQ-а) до ФЯ как до Пекина раком.

VD>>ОК, принимается. С оговоркой. Ленивые списки (или их аналоги) сейчас есть практически везде. И функции склеивать можно даже в C#. А уж для разных ОКамлов и Немерлов это самая, что ни на есть банальщина.


L>а) А если не списки?


То и это редкость ради которой не стоит иметь тот геморрой и проблемы с производительностью которые появляются в ленивых языках.

L>б) А что на Камлах и Немерлях пишут — map f . map g . map h? Или всё таки map (f . g . h)?


Там пишут по разному. Есть к примеру оператор |> который теми же F#-щиками юзается на право и на лево.
Результат получается аналогичным твоему примеру.

То что Парсек повторен на том же Немерле и реализация получилась вполне компактная не сильно заденет твое самолюбие?


VD>>Не видел подобных проблем в не ленивых языках.


L>Я же написал почему. В ленивом языке мы можем объединять их, потому что промежуточные структуры будут удаляться.

L>Давай вернёмся к нашему map f . map g . map h. Представь, что всё это осмысленные операции: foo = map f, goo = map g, hoo = map h.

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

L>И теперь нам надо foo.goo.hoo. В неленивом языке придётся выписывать map (f.g.h). Ну и где переиспользование в неленивом языке?


Да, пиши так же. Только используй foo_lazy.goo_lazy.hoo_lazy и вместо точки оператор >>.

L>Ладно. Я только к тому, что eDSL-и они же тоже для лаконичности, выразительности и всего-всего. И их можно не только на макросах делать. Но, если не хочешь, не будем это связывать.


Можно. А можно и на макросах. Причем то что скажем Лисп и Немерле имеют первоклассные макросы не отменяет возможности создавать и ДСЛ-и на базе комбинаторов. Пример с повторением Парсека на Немерле я тебе уже привел. Разве его существование не отрицается твоей теорией?

VD>>Вообще, надо бы стравить Лиспаря и Хаскелиста... и поглядеть на получившийся флэйм.

L>А что тут смотреть! Лисп мощнее (можно больше), Хаскель мягче (пользуем только уровень функций, никаких макр)

Да, то что каждый уперт в свою "правду" и кроме искр ничего не выйдет. Но искр будет много ,

L>Почему трёп? Почему понты?

L>Что же касается проблем — я сейчас не об этом спорю. Я говорю о ленивости, как о средстве писать лаконичный код.

Да согласная я! Согласная!!! При условии, что ты добавишь слово "иногда".
Вот только я тебе устал повторять. Она (ленивость) есть в ленивых по умолчанию языках.

Пойми, если бы ленивость действительно постоянно давала бы ощутимый выигрыш, то в Лиспе и Немерле давно бы сделали макрос:
lazy
{
  блок с ленивыми по умолчанию вычислениями.
}

и не парились бы.
Вот только овчинка выделки не стоит.

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

L>А что в С# код прямо так превращается в машинные команды, безо всяких разных преобразований?


С преобразованиями. Но преобразования эти просты и линейны, так как система одна и та же — Фоннэймоновская.

L>Насчёт оптимизаций — давай без риторических вопросов, что ты хочешь узнать? В GHC есть оптимизации, могу показать много. Всё соптимизировать разумеется нельзя. Хотя бы в силу того, что уже соптимизированное соптимизировать трудно.


Хочу узнать когда Хаскель порвет (ну или хотя бы приблизится) по скорости MS С++ (об Intel я вообще молчу) скажем на тесте альфа-блэнда пробегавшем у нас в Философии?

L>Где чушь?


В предпосылках.

L>Повторю свою мысль — цепочка неленивых map/filter/fold неэффективна. Обосную — в силу создания промежуточных структур.


Вот это и есть чушь. Цепочка ЛЮБЫХ map/filter/fold неэффективна в сравнении с аналогичным императивным кодом в силу наличия лишних телодвижений и косвенности. Единственный верный путь оптимизации этих цепочек — это суровый инланинг и превращение их в банальные циклы. Тогда не будет не только промежуточных структур данных, но и вообще ничего лишнего. Будет только сам алгоритм приведенный к виду наиболее эффективно вычисляемому на современных процессорах.

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

L>И зачем ты мне про LINK написал я не понимаю. Я же тебе написал про итераторы, как ты хочешь моими же аргументами эти же аргументы опровергнуть?


Твои аргументы за ленивый язык. А это пример ленивой обработки списков (притом весьма выразительной) в на сквозь императивном не ленивом языке. Понятно?

VD>>Скорее обратное доказательства. Если обработка не переписана в код аналогичный for, то ее скорость по любому оставляет желать лучшего. А добиться отложенности вычислений на современных процессорах без доп.затрат нельзя в принципе.


L>Нет, не скорее. Заявление сделал ты, тебе и доказывать. Насчёт обработки в аналогичный for — смотри на оптимизацию под названием stream fusion.


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

В теории практика и теория аналогичны.
На практике же — нет.


L>Сомневаюсь. Я имею в виду, что ты дизайнил задачу в ленивых структурах и функциях, реализовывал это на ленивом языке? И тем не менее не увидел преимущества лени? Это очень странно.


Мне надоело отвечать на одни и те же вопросы по сто раз. Отвечаю в последний раз. Увидел. Но не везде и не увидел зачем для этого иметь ленивый язык.

L>Для ясности — я не говорю о преимуществе, как о доминантной черте, которая перевешивает всё и вся и давайте теперь дружно писать лениво. Лаконичность — один из бенефитов ленивости, и я доказываю только это.


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

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

L>При чём здесь монады?


Притом, что их повсеместное применение в Хаскле как раз вызвано его ленивостью. В обычных языках монады могут понадобиться раз в год. Скажем в F# вот сделали интересное решение для поддержки параллельных вычислений на их базе. Такое их применение я расцениваю как красивое решение. А выводить с их помощью значения на консоль — это, извините за грубость — маразм!

L>А стриктнесс в Хаскеле достигается совсем другими механизмами. Подавляющее большинство монад — ленивы. Я же говорю — не разобрался.


Да, ну? Другими средствами? Ой как я сер! Просвети, плиз. Что за другие механизмы такие?

Что же до ленивости монад, то как я их понимаю — это средство заставить вычисления быть последовательными. Конечно можно углядеть ленивость и в монадах, но их суть как раз борьба с ленивостью в отдельных участках программы.
Ты по всей видимости перепутал термины "последовательные" и "с побочными эффектами".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Ленивые языки - за и против
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.08 06:05
Оценка:
Здравствуйте, VoidEx, Вы писали:

VD>>Может быть. Только я таких не знаю. Идею применять монады для того чтобы сделать код последовательным нельзя не только назвать простой, но и здоровой. Это же надо так извращаться чтобы достичь то, что и так есть?

VE>А в чём ты углядел извращение? Там сложного ничего нет.

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

VE>Применение итераторов для достижения ленивости — это просто и здраво?


Они применяются чтобы написать 3-5 базовых функций. Далее ты можешь комбинировать их точно так же как в ленивом языке.

Собственно я не буду спорить с тем, что можно придумать и более удобные абстракции порождения ленивых списков. Но и этого достаточно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Ленивые языки - за и против
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.08 06:28
Оценка:
Здравствуйте, thesz, Вы писали:

VD>>ОК, принимается. С оговоркой. Ленивые списки (или их аналоги) сейчас есть практически везде. И функции склеивать можно даже в C#. А уж для разных ОКамлов и Немерлов это самая, что ни на есть банальщина.


T>I believe it when I see it.


T>Как минимум для OCaml ты не прав.


T>Rewrite rules для OCaml нет. Более того, deforestation (которая склейка функций) для строгих языков может изменить семантику программы. Без этой оптимизации программа не будет работать, а с оптимизацией — будет. Поэтому такие преобразования никто для ML семейства не пишет (за исключением Lazy ML).


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

L>>>3. Соответственно подобное разделение позволяет выписывать комбинаторы и использовать их отдельно. Повторное использование, что тоже показатель лаконичности.

VD>>Не видел подобных проблем в не ленивых языках.

T>Какие комбинаторы ты на них писал?


Разные. В прочем, я по возможности обхожусь без них.
Пример реализации Парсека на Немерле тебя устроит?

L>>>4. eDSL без макросов — следствие ленивости (одна из причин)!

VD>>Ой. Только не на до про ДСЛ-и. Ладно? Есть разные пути их создания.
VD>>Вообще, надо бы стравить Лиспаря и Хаскелиста... и поглядеть на получившийся флэйм.

T>Лисперы быстро обижаются и отваливаются. Проходили. Они же как дети.


Лисперы и хаскелисты — это два лагера которые друг-друга стоят. Каждый прет свою линию и не слушает аргументов оппонента. А я вот как человек со стороны (не лиспер и не хаскелист) позицию лисперов разделяю больше. В Лиспе ДСЛ-и на каждом шагу. Они там базовый строительный элемент. Хаскель этим похвастаться не может.

T>Лично для меня сейчас написание последовательного кода на Java является проблемой.


Пиши не последовательный. Про Functional Java слышал?

T>Там надо думать, что за чем идёт.


Ой-йой-йой! Ужас! Ну, думай о том, как связывать одно вычисление с другим по средствам монад. Functional Java и Callabe тебе в путь.

T>И переменные можно переписать, а значит, испортить.


Ужас то какой?
Скачай Scala и используй def.

T>О!

T>Я так и знал.
T>Всё сведётся к банальной оптимизации.

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

T>Тебе сперва проблему надо решить, а потом оптимизировать решение.


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

L>>>1. В цепочке map/filter/fold важно ленивы они или нет. Неленивые — неэффективны (или вообще невозможны для бесконечных списков). Поэтому так популярны итераторы.

VD>>Чушь полнейшая. Во-первых, только у теоретиков везде возникают бесконечные списки. У всех остальных есть списко и его надо обработать. 99% программистов их до сих пор for-ами на Cxx обрабатывают. Ну, и если вдруг появляется нужда в ленивых map/filter/fold, то нет проблем их использовать. Как, по-твоему, работают Select, Where, Aggregate в LINQ?

T>Это когда появилось-то? Год назад?


В C# — да, год. Итераторы на которых реализованы эти функции имеются в C# уже 5 лет. А базовые примитивы (итераторы) на которых можно было реализовать данные функции были в Яве с ее рождения. А это год эдак 95-ый.

T>А почему появилось-то?


Спасибо в том числе и Хаскелю. Но появилось же? Так что же теперь (в 2008-ом) использовать протухшие аргументы?

L>>>2. Про медленную ленивую обработку списков — это утверждение тоже требует доказательства

VD>>Скорее обратное доказательства. Если обработка не переписана в код аналогичный for, то ее скорость по любому оставляет желать лучшего. А добиться отложенности вычислений на современных процессорах без доп.затрат нельзя в принципе.

T>Вот, смотри: http://thesz.mskhug.ru/browser/hiersort/core/S.hs

T>Это ядро моей самопальной системы моделирования аппаратуры.
T>Оно пишется за 15 минут и сразу готово к использованию.
T>Такое же дело на сообщениях для Эрланга товарищ Gaperton продумывал в районе недели, не меньше.

Ну, я же не говорил, что Гапертон гений, а ты нет?

Какое это имеет отношение к делу?

T>Монады-то здесь причём?

T>Монады к strictness отношения не имеют.

Еще один. Ну, покажи как достичь ее без монад.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Ленивые языки - за и против
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.08 06:40
Оценка:
Здравствуйте, yumi, Вы писали:

L>>>Для начала классика: Why FP matters. Must read.

VD>>Спасибо, религиозным чтивом не увлекаюсь. В свое время не осилил даже Майн Камф.

Y>Может наоборот, религия не позволяет прочитать? Или лень? Если второе, то да, ленивость по умолчанию это плохо


Религия позволяет — я атеист.
Поглядел... Ничего ровным счетом там нет. Как нет и слов о том, что язык обязан быть ленивым по умолчанию. Приводится два примера когда ленивые списки упрощают реализацию. Такие вещи пишутся с пол пинка.
http://rsdn.ru/forum/message/3219173.1.aspx
Автор: VladD2
Дата: 18.12.08


Y>И именно поэтому, это дает выигрыш, кумулятивный эффект видите ли.


В упор не вижу этого.

L>>>4. eDSL без макросов — следствие ленивости (одна из причин)!

VD>>Ой. Только не на до про ДСЛ-и. Ладно? Есть разные пути их создания.

Y>Я вижу два пути создания eDSL, это путь Лиспа (который кстати и использует Немерле) путем манипуляции АСТ. А есть второй путь, путь Хаскеля, он вообще я бы сказал ортогонален пути Лиспа. Можно конечно порассуждать на тему, плюсы и минусы обоих подходов, но что-то неохота


Я тебе больше скажу. Путь Хаскеля открыт для всех ФЯ в том числе и для Немерла с Окамлом. Реализацию Парсека на Немерле видел?

VD>>Вообще, надо бы стравить Лиспаря и Хаскелиста... и поглядеть на получившийся флэйм.


Y>Я бы поставил на Лиспаря, обычно от Хаскеллистов так и прет непонятным фанатизмом. В этом плане, Лисп все же более приземленный язык близкий к real-world.


фанатизмом прет от обоих. В прочем от Эрланговцев и Немерлистов тоже прет. Но от Хаскелисов и Лиспарей прет как-то особенно. С напором я бы сказал.
В прочем, я бы тоже поставил на Лиспаря. Для Лиспа ДСЛ-и — это строительный блок. Лисперы на них съели не только собак, но и другую живность.

VD>>А вот, то что код нельзя тупо превратить в машинные команды, а надо заниматься разными бета-редукциями — это проблема. Сколько слов сказано о том, что в Хаскеле все можно соптимизировать? И где эти оптимизации?


Y>Бедные Хаскеллисты, прям их жалко стало (пускаю скупую мужскую слезу) занимаются разными нехорошими и непонятными бета-редукциями А тем временем в деревне вилла-бадже дотнетисты и джависты не занимаются не понятными бета-редукциями, их код весело превращается сразу в машинные команды.




VD>>Чушь полнейшая. Во-первых, только у теоретиков везде возникают бесконечные списки. У всех остальных есть списко и его надо обработать. 99% программистов их до сих пор for-ами на Cxx обрабатывают. Ну, и если вдруг появляется нужда в ленивых map/filter/fold, то нет проблем их использовать. Как, по-твоему, работают Select, Where, Aggregate в LINQ?


Y>Бесконечный список, это абстракция. Она возникает не только у теоретиков, но и у практиков. Как и всякая любая абстракция, она призвана упростить понимание и использование такой сущности как список. В этом нет ничего плохого, как и в том, что 99% лет десять-двадцать назад писали на голом ассемблере без for-ов.


Я с этим и не спорю.

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


Y>Оргазмы лучше получать от других занятий


Дык. На том и стоим.

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


Ну, дык мужик должен получать оргазм от общения с любимым дел... э... телом. А для представителей альтернативный полов придумали бета-реду... э... вибратор.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Ленивые языки - за и против
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.08 06:56
Оценка: +1
Здравствуйте, awson, Вы писали:

G>>Меня бесполезно агитировать. И я не считаю Хаскель оптимальным выбором для очень широкого круга задач. И в особенности — высоконагруженных серверов. Как я сказал — верования меня не интересуют, меня интересуют факты, и рассуждения.

A>Вы, боюсь, недостаточно знаете Хаскелл, чтобы такие обсуждения имели смысл.

А ты уверен, что надо быть курицей, чтобы рассуждать о вкусе яичницы?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Ленивые языки - за и против
От: thesz Россия http://thesz.livejournal.com
Дата: 18.12.08 08:37
Оценка:
T>>Ленивость позволяет класть код так, как этого требует мысль, а не последовательность вычислений.
G>Функциональная чистота позволяет класть код так, как этого требует мысль, а не последовательность вычислений.

И да, и нет.

Напиши на функционально чистом подмножестве Эрланга вот такое:
f x y = z
  where
     z = g w
     w = m x y


И второе. Где у нас функциональная чистота чище всего? Правильно, в ленивых языках.

T>>Например, я часто применяю операции наподобие (head:tail) = someListThatMayBeEmpty и потом беру результаты этого опасного сравнения с образцом исходя из других критериев, когда, например, этот список точно не может быть пуст.

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

Потому, что 1) источник сравниваемого выражения вычисляется, 2) голова и хвост используются в нескольких выражениях.

Это только выглядит странно, а на самом деле очень удобно.

T>>В результате мой код полон ленивых сравнений с образцом и, соответственно, он сильно завязан на ленивые вычисления.

G>Я так понимаю, ты сторонник обфускации, потому что не любишь, когда чужие люби читают твои программы.

С чего бы это?

Сторонники обфускации все собрались в лагере JK.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[9]: Ленивые языки - за и против
От: thesz Россия http://thesz.livejournal.com
Дата: 18.12.08 09:06
Оценка:
VD>>>ОК, принимается. С оговоркой. Ленивые списки (или их аналоги) сейчас есть практически везде. И функции склеивать можно даже в C#. А уж для разных ОКамлов и Немерлов это самая, что ни на есть банальщина.
T>>I believe it when I see it.
T>>Как минимум для OCaml ты не прав.
T>>Rewrite rules для OCaml нет. Более того, deforestation (которая склейка функций) для строгих языков может изменить семантику программы. Без этой оптимизации программа не будет работать, а с оптимизацией — будет. Поэтому такие преобразования никто для ML семейства не пишет (за исключением Lazy ML).
VD>Нет нужны заниматься математическим онанизмом чтобы получить ленивый список или "склеить" ленивые функции. Как и нет нужны говорить об оптимизациях там где о них и речи не было. Так же не стоит думать, что оптимизации безуспешно применяемые в Хаскеле — это единственный верный путь.

"Безуспешно" — это ты со зла.

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


Supero? Если уж говорить о производительности программ.

Я больше забочусь о производительности программиста.

Это его время сейчас ценнее всего.

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

Это может занять много времени, но!

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

L>>>>3. Соответственно подобное разделение позволяет выписывать комбинаторы и использовать их отдельно. Повторное использование, что тоже показатель лаконичности.

VD>>>Не видел подобных проблем в не ленивых языках.
T>>Какие комбинаторы ты на них писал?
VD>Разные. В прочем, я по возможности обхожусь без них.
VD>Пример реализации Парсека на Немерле тебя устроит?

Почти.

Попробуй реализовать что-нибудь вроде Deterministic, error-correcting parser combinators.

В Парсеке всего одно место, где нужна ленивость.

К тому же, он являет собой пример не совсем хорошего дизайна, например, часть грамматики наподобие (char 'a' >> char 'b' >> char 'c' >> return ()) <|> return () может пропустить до двух символов по возвращению. Об этом надо помнить, и это напрягает.

T>>Лисперы быстро обижаются и отваливаются. Проходили. Они же как дети.

VD>Лисперы и хаскелисты — это два лагера которые друг-друга стоят. Каждый прет свою линию и не слушает аргументов оппонента. А я вот как человек со стороны (не лиспер и не хаскелист) позицию лисперов разделяю больше. В Лиспе ДСЛ-и на каждом шагу. Они там базовый строительный элемент. Хаскель этим похвастаться не может.

Я не фанат определённого ЯП или подхода.

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

Если выгоден DSEL — будет DSEL. Нужен императивный язык — будет императивный (но как можно меньше). И тп.

T>>Лично для меня сейчас написание последовательного кода на Java является проблемой.

VD>Пиши не последовательный. Про Functional Java слышал?

Не могу. Надо последовательный. Требования.

T>>Там надо думать, что за чем идёт.

VD>Ой-йой-йой! Ужас! Ну, думай о том, как связывать одно вычисление с другим по средствам монад. Functional Java и Callabe тебе в путь.

В монадах тоже надо думать о последовательности, поэтому у меня их немного.

T>>И переменные можно переписать, а значит, испортить.

VD>Ужас то какой?
VD>Скачай Scala и используй def.

Нельзя. Надо использовать Java.

T>>О!

T>>Я так и знал.
T>>Всё сведётся к банальной оптимизации.
VD>Я бы сказал к банальной жизни. Можно долго писать кипятком от ленивости, но когда приходят реальные дела, то кипятком сыт не будешь.

То есть, я делаю нереальные дела.

Это самый лучший комплимент за всю историю моего пребывания на RSDN.

Спасибо.

T>>Тебе сперва проблему надо решить, а потом оптимизировать решение.

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

Видимо, у тебя проблемы либо простые, либо уже тобой решённые неоднократно.

Это нормально, нечего этого стыдиться.

А я сейчас пишу преобразование VHDL в нетлист. И моделирование поведения оного нетлиста. Я никогда этого не делал. И никто из моих знакомых этого не делал.

VD>В C# — да, год. Итераторы на которых реализованы эти функции имеются в C# уже 5 лет. А базовые примитивы (итераторы) на которых можно было реализовать данные функции были в Яве с ее рождения. А это год эдак 95-ый.


Они были неполиморфны, посему практически непригодны.

T>>А почему появилось-то?

VD>Спасибо в том числе и Хаскелю. Но появилось же? Так что же теперь (в 2008-ом) использовать протухшие аргументы?

Действительно.

Я не понимаю, зачем ты используешь протухшие аргументы.

Если быть серьёзным, то 1) оные ленивые вычисления пришлёпнуты, иначе не назовешь, и их применение из-за этого ограничено, и 2) обширной практики использования их в языке нет.

Грубо говоря, вы не знаете, где и с чем столкнетесь при их использовании. Вдруг у вас память потечёт со страшной силой?

T>>Вот, смотри: http://thesz.mskhug.ru/browser/hiersort/core/S.hs

T>>Это ядро моей самопальной системы моделирования аппаратуры.
T>>Оно пишется за 15 минут и сразу готово к использованию.
T>>Такое же дело на сообщениях для Эрланга товарищ Gaperton продумывал в районе недели, не меньше.
VD>Ну, я же не говорил, что Гапертон гений, а ты нет?
VD>Какое это имеет отношение к делу?

Это простой пример, как ленивые списки вылезают в практических задачах.

T>>Монады-то здесь причём?

T>>Монады к strictness отношения не имеют.
VD>Еще один. Ну, покажи как достичь ее без монад.

Вот ты написал:
f :: Int -> Int -> Int
f a b = a + b

Выглядит лениво. Вместо результата будет замыкание ((+) a b), где и аргументы — замыкания.

Пишем так:
f :: Int -> Int -> Int
f 0 b = b
f a b = a+b

Здесь форсируется первый аргумент перед вычислением.

Всё равно мало.

Пишем вот этак:
f :: Int -> Int -> Int
f !a !b = let s = a + b in s `seq` s


Вуаля!

При вызове мы форсанём оба аргумента, да ещё и сумму.

Такие вещи надо расставлять только в определённых местах, многое выводит компилятор.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[7]: Ленивые языки - за и против
От: thesz Россия http://thesz.livejournal.com
Дата: 18.12.08 09:38
Оценка:
T>>Так что я не вижу причин, по которым надо это заминать.
G>Ну, если бы ты видел причины, то не заставил бы меня напоминать тебе, что:
G>1) ни одного коммерческого ПО, которое дошло бы до продакшн, и которому требуется поддержка, ты на Хаскеле не написал.

Ээээ. И?

(Найдешь контраргумент к своим собственным словам, или подсказать?)

G>2) Твой опыт исключается двумя темами, из которых одну вы с potan не доделали, а вторая — это архитектурные прототипы харда, который ты делал в одиночку на выброс.


Я совсем не понял этого предложения.

G>3) Ни одна из этих программ не работала на пределе возможностей оборудования, и не была интерактивной.


Ээээ. И?

T>>Видимо, то было лично, вне просторов RSDN, а это "не считается".

G>Видимо, сейчас ты просто придумываешь те события, которых не было.

Это было при свидетелях. При том же самом potan.

Действительно, всё, что вне просторов RSDN, в зачёт не идёт.

Запомню.

T>>И как ты просто обязан знать, "знать и применять" не означает "способен просто и доходчиво объяснить другим".

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

Личное общение и общение через форум полностью эквивалентны?

T>>>>Как контролируются задержки в ленивом ФЯ, я уже рассказывал. Как и всё в таких ФЯ, они контролируются высокомодульно — есть генератор, есть потребитель. Потребитель потребляет создаваемое, пока не сочтёт, что упёрся или не завершится время на решение.

G>>>Я тебя просил привести пример. Пример будет?
T>>Я не смогу написать что-то, отличное от абзаца выше.
G>Ты не сможешь этим методом контроллировать задержку, вознкающую на накопившейся невычисленной цепочке. Ты не сможешь доказать отсутствия возможности накопления таких цепочек. Поэтому, ты никак не можешь контроллировать эти задержки, не поставив везде strictness.

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

Это не жёсткие гарантии, это наиболее вероятное поведение программы.

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

И это я могу показывать экспериментально.

T>>Я повторю свой вопрос: О чем же мы тогда спорим?

T>>Какой тезис я доказываю, с твоей точки зрения?
G>Начал ты с того, что обвинил меня в преждевременной оптимизации.

Формально там обвинения нет.

Более того, история началась не там, она началась где-то ещё. AFAIR.

Добавлю, что формально ты прав, конечно. За исключением того, что это не ответ на вопрос о тезисе, это рассказ об исторических событиях.

G>Потом я сказал, что считаю lazy annotation более продуктивной, чем strictness annotation. Привел обоснование. И попросил тебя по правилам это опровергнуть.


Опять не о моём тезисе.

Кстати.

Тут рядом очень интересное (я умею учиться и на чужом опыте тоже):

Видишь ли, я для себя всегда сам решаю, что для меня перевешивает.
http://rsdn.ru/forum/message/3218948.1.aspx


То есть, ты не выдаешь критериев, которым должны соответствовать примеры или доказательства, а оставляешь решение за собой.

То есть, никто никогда не сможет соответствовать твоим внутренним критериям, пока ты так не решишь.

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

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


Карма любых форумов действительно не очень, если на карту поставлено что-то выше снятия проститутки.

Комментарии вредны для свободы слова

G>Примерно такая хронология событий. А-аставайтесь с нами.


Здесь я оказался "волею судеб".

Придётся.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.