thedeemon: (Default)
[personal profile] thedeemon
Читаю статью про F# в очередном номере ПФП, а там стандартный набор бреда про сабж:
В противоположность жадному подходу существует стратегия ленивых вычислений, которая позволяет вычислять значение выражения только тогда, когда оно становится необходимо. Преимуществами такого подхода являются:
• производительность, поскольку неиспользуемые значения просто не вычисляются;
• возможность работать с бесконечными или очень большими последовательностями, так как они никогда не загружаются в память полностью;
• декларативность кода. Использование ленивых вычислений избавляет программиста от необходимости следить за порядком вычислений, что делает код проще.


По пунктам:
1.
а) Что-то я не припомню, чтобы программисты на неленивых языках стали бы вычислять какие-то значения, которые потом не используют. Обычно все-таки люди достаточно разумны, чтобы их программы вычисляли ровно столько, сколько нужно.
б) Ленивость создает накладные расходы, причем существенные. Если две программы делают одно и то же, ленивый вариант никак не будет производительнее энергичного. Почему-то большинство проблем с производительностью программ на Хаскеле решают именно расстановкой всяких ! и $!, убирающих ленивость. И оптимизатор тем же занимается.

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

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

Date: 2010-05-22 07:14 pm (UTC)
From: [identity profile] awson.livejournal.com
Статью не читал и не буду, процитированный кусок действительно плох. Однако, в какой-то мере выступлю за авторов:

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

2. В таком духе можно говорить о чем угодно. Речь же идет о выразительности. Кстати, из теории следует, что non-strict порядок вычислений *строго* выразительнее strict порядка.

3. Теоретически да. Но практически (не говорю об игрушечных языках) существует единственный чистый и единственный ленивый и это один и тот же язык - Haskell. В нем, если на минуту забыть об unsafe конструкциях, нет *неконтролируемых* побочных эффектов в духе любого типичного императивного языка и нет проблемы reasoning о порядке вычислений. Для нечистых же языков вообще нет никакой теории, которая хотя бы позволила дать для них определение non-strict семантики. Поэтому непонятно в каком контексте тут можно "думать о порядке вычислений гораздо больше обычного". При этом в таком (почти) строгом языке, как C/C++, порядок вычислений не прост и не понятен - загляните, например, в уложение о sequence points.

Date: 2010-05-22 08:10 pm (UTC)
From: [identity profile] thesz.livejournal.com
>Поэтому непонятно в каком контексте тут можно "думать о порядке вычислений гораздо больше обычного".

LazyML

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

Date: 2010-05-22 09:11 pm (UTC)
From: [identity profile] awson.livejournal.com
Я никогда не вникал и думал, что "ML" в LazyML это просто дань системе типов Хинли-Милнера, поскольку ML был первым, а на на самом деле оно - (пре)Хаскелл.

Date: 2010-05-22 08:55 pm (UTC)
From: [identity profile] usovalx.livejournal.com
А Clean и Miranda чем не угодили?

Date: 2010-05-22 09:08 pm (UTC)
From: [identity profile] awson.livejournal.com
Ну Clean мне как-то даже в голову не пришел. Он у меня когда-то очень давно как двойник Хаскелла поканал - я и забыл о нем.

Но смысл все равно один: в природе не существует работающих нечистых ленивых языков. Вот, правда, выше thesz указал на LazyML, для меня сюрприз, что он нечистый, я всегда был уверен, что LML это HBC, то есть Хаскелл.

Date: 2010-05-22 09:57 pm (UTC)
From: [identity profile] thesz.livejournal.com
http://www.csse.monash.edu.au/~lloyd/tildeFP/LML/

В системе типов LazyML не было разделения на чистые выражения и выражения с побочным эффектом.

Ну, и в примерах видно, как делалось IO. И насколько всё это было хрупким. ;)

Date: 2010-05-23 04:18 am (UTC)
From: [identity profile] thedeemon.livejournal.com
1. Согласен. И они прилагаются, как и многие другие. Просто исходное высказывание можно прочитать так, будто добавление в программу ленивой семантики повышает производительность.

2. Да, выразительность в ленивом языке выше. Да, теоретически можно выполнять более широкий класс программ. Об этом и надо писать, а не о бесконечных последоветельностях.

3. Я проблемы в Хаскелле и имел в виду - сколько раз начинающие программисты попадали в засаду с монадой ЙО, когда файл вдруг закрывался до начала чтения или операции с сетью откладывались до конца сессии. Эти проблемы реальны и регулярно случаются. И именно из-за смеси ленивости и сайд эффектов.

Date: 2010-05-23 06:31 am (UTC)
From: [identity profile] awson.livejournal.com
3. Тут дело не в монаде IO, а в использовании небезопасных функций т.н. "ленивого" IO, которые на самом деле *нарушают* чистоту, т.е. все последствия их использования ложатся на использующего. Все они базируются на unsafeInterleaveIO, которая явно маркирована как unsafe. Другое дело, что правильно было их также эксплицитно маркировать как unsafe, типа unsafeHGetContents вместо hGetContents и т.д.

Date: 2010-05-30 07:50 pm (UTC)
From: [identity profile] beroal.livejournal.com
начинающие программисты попадали в засаду с монадой ЙО, когда файл вдруг закрывался до начала чтения
Они делали hGetContents и hClose?

Date: 2010-05-31 05:46 am (UTC)
From: [identity profile] thedeemon.livejournal.com
Возможно. Не помню подробностей, но в форумах и мэйллистах подобные вопросы регулярно бывают.

Date: 2010-05-31 08:45 am (UTC)
From: [identity profile] beroal.livejournal.com
Я тоже не экстрасенс. Будем считать, что начинающие программисты виноваты сами. :)

Profile

thedeemon: (Default)
Dmitry Popov

December 2025

S M T W T F S
 12 3456
789101112 13
14151617181920
21222324252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 30th, 2026 05:22 pm
Powered by Dreamwidth Studios