Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 15.02.07 08:49
Оценка: +1
Женя,

E>Провожу тут для себя одно изыскание по языкам программирования и обнаружил интересный факт: оказывается, в языке Simula уже была такая штука, как Call by name. С помощью которой приведенный выше код unless мог быть написан и в чисто императивной Simula.


Проблема в том, что call-by-name в оригинальном виде совершенно непригодно к использованию. На практике это эмулируется стратегией call-by-need, что очевидно влечёт непредсказуемый результат в общем случае в условиях побочных эффектов.

Практически, однако, вопрос о соотношении
1) дефолтной ленивости с опциональной энергичностью и анализатором энергичности (strictness analyser) как в Хаскелле, и
2) дефолтной энергичностью с опциональной ленивостью (как в Ocaml, Scala, N, etc)
остаётся открытым и требует особого обсуждения.

Лучше завести новый топик.

16.02.07 03:51: Ветка выделена из темы call-by-name, call-by-need...
Автор: eao197
Дата: 15.02.07
— VladD2
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re: Ленивость или Энергичность по умолчанию?
От: Курилка Россия http://kirya.narod.ru/
Дата: 15.02.07 09:04
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Лучше завести новый топик.


Может откуда-нибудь "отгрызём" ветку?
Re: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 15.02.07 09:08
Оценка:
LCR>На практике это эмулируется стратегией call-by-need, что очевидно влечёт непредсказуемый результат в общем случае в условиях побочных эффектов.

Да, забыл сказать, что Хаскелл определяется не как lazy язык, а как non-strict язык. Из-за этого возникают определённые терминологические флуктуации, откуда возникает путаница.

From what I understand, non-strict semantics are (very informally) about choosing an order of evaluation that, where possible, avoids non-termination or error. Laziness is about evaluating only what's needed.
In any case, I think all of the mainstream Haskell compilers and interpreters implement the non-strict semantics by means of lazy evaluation, so unless you're working on a radical new Haskell implementation, you probably don't need to worry about the difference.


То есть в принципе, call-by-need, non-strict и lazy не одно и то же, но разница с точки зрения практики столь незначительна, что можно не принимать во внимание.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 15.02.07 09:10
Оценка:
Кирилл,

LCR>>Лучше завести новый топик.


К>Может откуда-нибудь "отгрызём" ветку?


Пока нечего отгрызать.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.02.07 00:53
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Практически, однако, вопрос о соотношении

LCR>1) дефолтной ленивости с опциональной энергичностью и анализатором энергичности (strictness analyser) как в Хаскелле, и
LCR>2) дефолтной энергичностью с опциональной ленивостью (как в Ocaml, Scala, N, etc)
LCR>остаётся открытым и требует особого обсуждения.

На сегодня я голосую за второй пункт, так как технологии оптимизации не дошли до того состояния чтобы обеспечить приемлемую производительность линивого кода. Умолчальная неленивость в сочетании с опциональной ленивостью позволяет решать все вопросы с приемлемым качеством и одновремнно обеспечивает удобство.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Ленивость или Энергичность по умолчанию?
От: BulatZiganshin  
Дата: 16.02.07 07:32
Оценка:
LCR>>Практически, однако, вопрос о соотношении
LCR>>1) дефолтной ленивости с опциональной энергичностью и анализатором энергичности (strictness analyser) как в Хаскелле, и
LCR>>2) дефолтной энергичностью с опциональной ленивостью (как в Ocaml, Scala, N, etc)
LCR>>остаётся открытым и требует особого обсуждения.

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


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

далее идёт такое соображение — как минимум 80% кода программы вообще не требует оптимизации, для многих программ оптимизация не нужна вообще

а вообще, strict (или по крайней мере eager) реализация(и) хаскела существует. у меня даже была идея препроцессора, который "стриктизирует" хаскел код, скажем из такого:

fac 0 = 1
fac n = n*fac(n-1)

делает такой:

fac !0 = 1
fac !n = let t = fac $! (n-1)
         in t `seq` n*t
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 16.02.07 09:01
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>а вообще, strict (или по крайней мере eager) реализация(и) хаскела существует. у меня даже была идея препроцессора, который "стриктизирует" хаскел код


Библиотечные то функции он не стриктанёт
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Ленивость или Энергичность по умолчанию?
От: BulatZiganshin  
Дата: 16.02.07 09:03
Оценка: :)
Здравствуйте, lomeo, Вы писали:

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


BZ>>а вообще, strict (или по крайней мере eager) реализация(и) хаскела существует. у меня даже была идея препроцессора, который "стриктизирует" хаскел код


L>Библиотечные то функции он не стриктанёт


они тоже написаны на хаскеле
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.02.07 16:25
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>далее идёт такое соображение — как минимум 80% кода программы вообще не требует оптимизации, для многих программ оптимизация не нужна вообще


99% кода не требуют ленивосити, а замедление просходит всгда.
К тому же твои 80% высасаны из пальца. Мои задачи все идут на пределе современного железа. И линшей скорости у меня нет. Поэтому Хаскель для меня не приемлем в принципе. Я не готов отказаться от более сложных задач только ради мнимых приемуществ ленивости.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Ленивость или Энергичность по умолчанию?
От: BulatZiganshin  
Дата: 16.02.07 16:33
Оценка:
Здравствуйте, VladD2, Вы писали:

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


BZ>>далее идёт такое соображение — как минимум 80% кода программы вообще не требует оптимизации, для многих программ оптимизация не нужна вообще


VD>99% кода не требуют ленивосити, а замедление просходит всгда.


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

VD>К тому же твои 80% высасаны из пальца. Мои задачи все идут на пределе современного железа. И линшей скорости у меня нет. Поэтому Хаскель для меня не приемлем в принципе. Я не готов отказаться от более сложных задач только ради мнимых приемуществ ленивости.


уверяю тебя, что не меньше 80% кода в твоих задачах вообще не сказывается на конечной проивзодительности продукта. это я в общем-то нижнюю границу назвал. ну и твои задачи на работе могут быть весьтма специфичными, в общем и целом на первом месте функциональность и надёжность. скажем, в твоих rsdn'овских продуктах ни о каких "на пределе железа" речи быть не может
Люди, я люблю вас! Будьте бдительны!!!
Re: Ленивость или Энергичность по умолчанию?
От: palm mute  
Дата: 16.02.07 16:47
Оценка: +2
Lazy Cjow Rhrr wrote:
>
> Практически, однако, вопрос о соотношении
> /1)/ дефолтной ленивости с опциональной энергичностью и анализатором
> энергичности (strictness analyser) как в Хаскелле, и
> /2)/ дефолтной энергичностью с опциональной ленивостью (как в Ocaml,
> Scala, N, etc)
> остаётся открытым и требует особого обсуждения.
>
> Лучше завести новый топик.

Хоть ты и не спрашивал, но народ начал голосовать, потому мои 5 копеек:
лично я больше игрался с Окамлом, чем с Хаскеллом. Так вот,
необходимость большинство функций работы со списками делать
хвостато-рекурсивными (делать внутренний цикл с аккумулятором, а при
возврате значения разворачивать список) — напрягает. Выбирать между map
и rev_map напрягает. Знать заранее, много ли получится элементов в
списке (и выбирать между энергичным списком и ленивым потоком) —
напрягает. Разные fold'ы и map'ы для потоков и списков — некошерно. Вот.

з.ы. очень понравился ответ apfelmus'а на твой вопрос:
http://www.nabble.com/forum/ViewPost.jtp?post=9004809&amp;framed=y

з.з.ы. если вдруг кто напишет ответ — я смогу прочесть только через неделю
Posted via RSDN NNTP Server 2.0
Re[5]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.02.07 16:53
Оценка: :)
Здравствуйте, BulatZiganshin, Вы писали:

BZ>вот не сказал бы. в хаскеле даже чтение входного потока ленивое.


Оно везде ленивое. Ну, и что? А вся обработка не ленивая. И ленивость достигается банальными средствами вроде итераторов или просто вызовом функции вадающей за раз по символу/строке.

BZ> так что тут дело в перестройке мышления, перестроишь — и у тебя неленивые алгоритмы будут получаться лишь с большим напрягом помнишь, я даже 5-ти строчную программу сделал эффектвиныей с помощью лени?


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

VD>>К тому же твои 80% высасаны из пальца. Мои задачи все идут на пределе современного железа. И линшей скорости у меня нет. Поэтому Хаскель для меня не приемлем в принципе. Я не готов отказаться от более сложных задач только ради мнимых приемуществ ленивости.


BZ>уверяю тебя, что не меньше 80% кода в твоих задачах вообще не сказывается на конечной проивзодительности продукта.


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

Тебе же я это сказал, чтобы ты не говорил за всех.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 19.02.07 04:33
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Практически, однако, вопрос о соотношении

LCR>1) дефолтной ленивости с опциональной энергичностью и анализатором энергичности (strictness analyser) как в Хаскелле, и
LCR>2) дефолтной энергичностью с опциональной ленивостью (как в Ocaml, Scala, N, etc)
LCR>остаётся открытым и требует особого обсуждения.

А в чем вообще преимущество ленивости?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Ленивость или Энергичность по умолчанию?
От: Quintanar Россия  
Дата: 19.02.07 08:37
Оценка:
Здравствуйте, AndreiF, Вы писали:

AF>А в чем вообще преимущество ленивости?


В том, что упрощается программа. Нет необходимости проверять граничные значения. Например, чтобы получить N элементов какой-либо последовательности, мы в энергичном языке должны писать compute_x N и в compute_x проверять это N, тогда как в ленивом языке эти детали можно опустить. Так же это помогает в случае, когда размер необходимых данных заранее неизвестен.
let fib = 1:1: (zip_with (+) fib (head fib)) - lazy variant, infinite list of fib numbers

let fib n = 
  if n = 0 then [1]
  else
    let _fib_acc n l = 
      if n = 0 then l
      else _fib_acc (n-1) (((head l) + (head (tail l))) :: l) in
    _fib_acc (n-1) [1; 1];;
Re[3]: Ленивость или Энергичность по умолчанию?
От: Quintanar Россия  
Дата: 19.02.07 08:39
Оценка:
Ошибся во второй функции, но мысль, я думаю, ясна.
Re[3]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 19.02.07 08:45
Оценка: +1
Здравствуйте, Quintanar, Вы писали:

То же самое можно сделать в энергичном языке при помощи итераторов, которые фактически являются локальным применением ленивости. А в чем преимущество ленивости везде и в обязательном порядке?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Ленивость или Энергичность по умолчанию?
От: Quintanar Россия  
Дата: 19.02.07 09:14
Оценка: +1 -1
Здравствуйте, AndreiF, Вы писали:
AF>То же самое можно сделать в энергичном языке при помощи итераторов, которые фактически являются локальным применением ленивости. А в чем преимущество ленивости везде и в обязательном порядке?

Ваши итераторы — суть костыли, писанина лишняя все равно нужна. Я же сказал, вообще, если отлечься от проблем с вводом-выводом, ленивые языки позволяют писать более простые программы за счет семантического упрощения (не надо обрубать концы цепочек вычисления вручную) + легко создавать бесконечные структуры данных.
Re[5]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 19.02.07 09:24
Оценка: +1
Здравствуйте, Quintanar, Вы писали:

Q>Ваши итераторы — суть костыли, писанина лишняя все равно нужна.


Какая еще писанина? В C#, например, всё делается очень просто и ненапряжно.

Q> Я же сказал, вообще, если отлечься от проблем с вводом-выводом, ленивые языки позволяют писать более простые программы за счет семантического упрощения (не надо обрубать концы цепочек вычисления вручную) + легко создавать бесконечные структуры данных.


Локальное применение ленивости позволяет делать то же самое, только без необходимости упражнять свою силу воли, пытаясь отвлечься от проблем с вводом-выводом, предсказуемостью производительности и отладкой.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 19.02.07 11:48
Оценка:
Здравствуйте, AndreiF, Вы писали:

Q>>Ваши итераторы — суть костыли, писанина лишняя все равно нужна.


AF>Какая еще писанина? В C#, например, всё делается очень просто и ненапряжно.


Может быть. Можно посмотреть реализацию ленивого map'а для ленивого списка?

Q>> Я же сказал, вообще, если отлечься от проблем с вводом-выводом, ленивые языки позволяют писать более простые программы за счет семантического упрощения (не надо обрубать концы цепочек вычисления вручную) + легко создавать бесконечные структуры данных.


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


Шкала ценностей у всех разная. Для кого то получаемые преимущества перекрывают все недостатки с лихвой.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Ленивость или Энергичность по умолчанию?
От: Кодт Россия  
Дата: 19.02.07 12:38
Оценка: 22 (3) +1
Здравствуйте, AndreiF, Вы писали:

Q>>Ваши итераторы — суть костыли, писанина лишняя все равно нужна.


AF>Какая еще писанина? В C#, например, всё делается очень просто и ненапряжно.


Но согласись, что любая ненулевая писанина — это больше и сложнее, чем нулевая

Q>> Я же сказал, вообще, если отлечься от проблем с вводом-выводом, ленивые языки позволяют писать более простые программы за счет семантического упрощения (не надо обрубать концы цепочек вычисления вручную) + легко создавать бесконечные структуры данных.


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


В caml ленивые данные имеют особый тип, и это правильно.
Но это значит, что
1) Хиндли-милнеровский полиморфизм уже не прокатит (прокатила бы перегрузка и шаблоны в стиле С++), придётся писать клоны функций над ленивыми аргументами. Например, продублировать всю коллекцию функций обработки списков.
2) Появляются новые виды списков
— фиксированный список фиксированных элементов
— фиксированный список ленивых элементов (т.е. ленивая голова cons-пары)
— ленивый список фиксированных элементов (т.е. ленивый хвост cons-пары)
— ленивый список ленивых элементов (ленивы и голова, и хвост)
Для первого или последнего в языках предусмотрен списочный (или, хотя бы, инфиксный) синтаксис, т.е. [a,b,c] или a:b:c:[]
вместо префиксного Cons a (Cons b (Cons c Nil)))
Для третьего — увы, увы.
3) Сопоставление с образцом перестаёт быть прозрачным.

Ну ладно, фиг с синтаксисом. Ради локального применения можно и потерпеть, тем более, что вряд ли кто будет писать длинные ленивые списки.
Но вот загромождение библиотеки стандартных алгоритмов не радует.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[7]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 19.02.07 12:52
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Может быть. Можно посмотреть реализацию ленивого map'а для ленивого списка?


В Хаскелле я пока что мало разобрался, так что сначала хотелось бы реализацию на нем.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Ленивость или Энергичность по умолчанию?
От: Klapaucius  
Дата: 19.02.07 13:28
Оценка: 6 (1) +1
Здравствуйте, lomeo, Вы писали:

L>Можно посмотреть реализацию ленивого map'а для ленивого списка?


Ленивый Map для любой последовательности.

IEnumerable<TR> Map<T, TR>(IEnumerable<T> seq, Func<T, TR> fun)
{
    foreach(T elem in seq) yield return fun(elem);
}
... << RSDN@Home 1.2.0 alpha rev. 655>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[8]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 19.02.07 13:30
Оценка:
Здравствуйте, AndreiF, Вы писали:

L>>Может быть. Можно посмотреть реализацию ленивого map'а для ленивого списка?


AF>В Хаскелле я пока что мало разобрался, так что сначала хотелось бы реализацию на нем.


Да это не Хаскелевская функция, она в большинстве ФЯ (и не ФЯ тоже многих) есть в стандартных библиотеках.

map f [] = []
map f (x:xs) = f x : map f xs


Т.е. с помощью функции одного аргумента переводит список в другой список, применяя эту функцию к каждому элементу списка.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 19.02.07 13:45
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Ленивый Map для любой последовательности.


K>
K>IEnumerable<TR> Map<T, TR>(IEnumerable<T> seq, Func<T, TR> fun)
K>{
K>    foreach(T elem in seq) yield return fun(elem);
K>}
K>


Спасибо, здорово! Ленивый список (конечный), получается, можно сделать очень легко. Вижу, что и другие рекурсивные типы тоже. Правильно я понимаю, что при втором обращении к этому IEnumerable результату он будет вести себя как уже подсчитанный?
Что относительно бесконечного списка?

IEnumerable<TR> Iterate<T, TR>(T start, Func<T> fun)
{
    while(true) {
      T next = fun(start);
        start = next;
        yield return next;
    }
}


Так сработает? Будет ли вести себя как подсчитанный при втором вызове? (Надо ли нам озаботиться хранением результата или это автомат?)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Ленивость или Энергичность по умолчанию?
От: Lloyd Россия  
Дата: 19.02.07 13:51
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Спасибо, здорово! Ленивый список (конечный), получается, можно сделать очень легко. Вижу, что и другие рекурсивные типы тоже. Правильно я понимаю, что при втором обращении к этому IEnumerable результату он будет вести себя как уже подсчитанный?

L>Что относительно бесконечного списка?

L>Так сработает? Будет ли вести себя как подсчитанный при втором вызове? (Надо ли нам озаботиться хранением результата или это автомат?)


Что вы имеете в виду под "подсчитанный"?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 19.02.07 14:07
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>>Так сработает? Будет ли вести себя как подсчитанный при втором вызове? (Надо ли нам озаботиться хранением результата или это автомат?)


L>Что вы имеете в виду под "подсчитанный"?


Второй раз будет вычисляться?

x = Iterate(1, x => x + 1);
foreach (... in x)
foreach (... in x) -- здесь второй раз будет вычисляться или будет использоваться накопленные данные?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Ленивость или Энергичность по умолчанию?
От: Lloyd Россия  
Дата: 19.02.07 14:11
Оценка:
Здравствуйте, lomeo, Вы писали:

L>>>Так сработает? Будет ли вести себя как подсчитанный при втором вызове? (Надо ли нам озаботиться хранением результата или это автомат?)


L>>Что вы имеете в виду под "подсчитанный"?


L>Второй раз будет вычисляться?


L>x = Iterate(1, x => x + 1);

L>foreach (... in x)
L>foreach (... in x) -- здесь второй раз будет вычисляться или будет использоваться накопленные данные?

Какие накопленные данные? Ничего не копится.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[12]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 19.02.07 14:20
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Какие накопленные данные? Ничего не копится.


Тогда это не ленивость. Семантика non-strict, да.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[13]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 19.02.07 17:29
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Тогда это не ленивость. Семантика non-strict, да.


Не могу уловить разницу между этими двумя понятиями. Можно подробнее?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Ленивость или Энергичность по умолчанию?
От: Klapaucius  
Дата: 19.02.07 17:34
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Спасибо, здорово! Ленивый список (конечный), получается, можно сделать очень легко. Вижу, что и другие рекурсивные типы тоже. Правильно я понимаю, что при втором обращении к этому IEnumerable результату он будет вести себя как уже подсчитанный?


Нет, не будет. Будет сгенерирован автомат, который никуда ничего не сохраняет. У этого, кстати, понятные преимущества и недостатки. Чтобы ленивая последовательность считалась один раз ее нужно обернуть во что-то вроде

public class LazyList<T> : IEnumerable<T>
{
    public LazyList(IEnumerable<T> seq)
    {
        _seq = seq;
    }

    IEnumerable<T> _seq;
    List<T> _buff = new List<T>();
    bool _calculated = false;

    private IEnumerable<T> Seq()
    {
        foreach (T elem in _seq)
        {
            _buff.Add(elem);
            yield return elem;

            // для демонстрации
            Console.WriteLine("side effect");
        }
        _calculated = true;
    }

    private IEnumerable<T> Select()
    {
        if (!_calculated)
            return Seq();
        else
            return _buff;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return Select().GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return Select().GetEnumerator();
    }
}


Понятно, что такой вот код

int[] arr = new int[3] { 1, 2, 3 };

LazyList<int> list = new LazyList<int>(arr);

foreach (int elem in list)
{
    Console.WriteLine(elem);
}

foreach (int elem in list)
{
    Console.WriteLine(elem);
}


выдаст

1
side effect
2
side effect
3
side effect
1
2
3


Понятно правда, что не вычислять первые N элементов бесконечного списка если они были вычислены ранее, а нам потребовались N+K с такой штукой не получится.
Что-то я затянул с этим вопросом, надо было писать "все вручную".

L>Что относительно бесконечного списка?


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

public static IEnumerable<double> RandomValues()
{
   Random rnd = new Random();
   while (true) yield return rnd.NextDouble();
}



L>
L>IEnumerable<TR> Iterate<T, TR>(T start, Func<T> fun)
L>{
L>    while(true) {
L>      T next = fun(start);
L>        start = next;
L>        yield return next;
L>    }
L>}
L>

L>Так сработает?

Так не сработает. А так сработает:

IEnumerable<T> Iterate<T>(T start, Func<T, T> fun)
{
    while (true)
    {
        T next = fun(start);
        start = next;
        yield return next;
    }
}
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[13]: Ленивость или Энергичность по умолчанию?
От: Кодт Россия  
Дата: 19.02.07 17:59
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Тогда это не ленивость. Семантика non-strict, да.


Потому что <бесконечные> структуры и <бесконечные> процессы — это разные вещи, и сравнивать их — сомнительный спорт.
(Разумеется, генератор бесконечной структуры — сам по себе является разновидностью бесконечного процесса).

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

Но уж в любом случае, если мы не клонируем переменную, а повторно используем — то было бы странно надеяться, что она будет меняться с исходной точки.
int x = 0;
for(int i=0; i!=10; ++i, ++x) {} // x = 0..9
for(int i=0; i!=10; ++i, ++x) {} // x = 10..19

int y = x; // клонируем
for(int i=0; i!=10; ++i, ++x) {} // x = 20..29
for(int i=0; i!=10; ++i, ++y) {} // y = 20..29

То же самое и с генератором.

Можно ли сделать в C#
IEnumerable generator() { .... yield return xxx; ..... }
.....
IEnumerable g = generator();
foreach(i in g) { ..... break; ..... }
IEnumerable h = g.Clone(); // <-- вот это? ну или что-то в таком роде?
foreach(i in g) { ..... break; ..... }
foreach(i in h) { ..... break; ..... }
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[7]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.02.07 03:48
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Может быть. Можно посмотреть реализацию ленивого map'а для ленивого списка?


Немерле-версия:
http://nemerle.org/svn/nemerle/trunk/lib/narray.n
/// Convert a sequence of one type to sequence of another type.
/// Convertion execute in lazy manner.
public MapLazy[From, To] (
    this source : SCG.IEnumerable [From],
    convert : From -> To
)
    : SCG.IEnumerable [To]
{
    foreach(elem in source)
        yield convert(elem)
}


А вот это по прикольнее будет:
public ExcludeLazy [T](
  [NotNull] this source  : SCG.IEnumerable [T],
  [NotNull]      exclude : SCG.IEnumerable [T]
)
  : SCG.IEnumerable [T]
{
  def ht = Hashtable();
  foreach (elem in exclude)
    ht[elem] = 0 : byte;

  foreach (elem when !ht.Contains (elem) in source)
    yield elem;
}

интересно прийдется объяснять, что делает эта фунция?

А вот применение в реальном коде:
http://nemerle.org/svn/vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Completion.n
def completeOverrides()
{
  def decl = this.Project.GetActiveDecl(fileIndex, line, col);

  match (decl)
  {
    | Type(builder)      => // Retrive overrides.
      match (builder.SuperClass())
      {
        | Some(typeInfo) =>
          def virtMod = NemerleAttributes.VirtualityModifiers & ~NemerleAttributes.New;
          def allOverrides = typeInfo.GetMembers(SR.BindingFlags.Instance 
            | SR.BindingFlags.NonPublic
            | SR.BindingFlags.Public).FilterLazy(m => m.Attributes %&& virtMod);
          def implemented = builder.GetMembers(SR.BindingFlags.Instance 
            | SR.BindingFlags.NonPublic
            | SR.BindingFlags.Public
            | SR.BindingFlags.DeclaredOnly).FilterLazy(m => 
              m.Attributes %&& NemerleAttributes.Override);
          def canOverride = allOverrides.ExcludeLazy(implemented);
          def res = canOverride.MapToArray(e => CompletionElem(
            (if (e is IProperty) GlyphType.Property else GlyphType.Method) :> int,
            e.Name, "info not implemented", array[Elem.Member(e)], 
            CompletionElemFlags.ForOverride));
          res;

        | _ => TopKeywords
      }
    | _ => TopKeywords
  }
}
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.02.07 03:48
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Но согласись, что любая ненулевая писанина — это больше и сложнее, чем нулевая


Дело в том, что фактическая писанина остается в библиотеке.
И в том, что "нулевая писанина" в Хаскеле в реальной жизни вылевается в тормоза и проблемы на ровном месте. В общем, ленивость по умолчанию — это не для реальной жизни.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.02.07 03:48
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Можно ли сделать в C#

К>
К>IEnumerable generator() { .... yield return xxx; ..... }
К>.....
К>IEnumerable g = generator();
К>foreach(i in g) { ..... break; ..... }
К>IEnumerable h = g.Clone(); // <-- вот это? ну или что-то в таком роде?
К>foreach(i in g) { ..... break; ..... }
К>foreach(i in h) { ..... break; ..... }
К>


В C# только если через рефлексию.
В Немерле можно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 08:39
Оценка:
Здравствуйте, AndreiF, Вы писали:

L>>Тогда это не ленивость. Семантика non-strict, да.


AF>Не могу уловить разницу между этими двумя понятиями. Можно подробнее?


Да тут вся ветка — обсуждение non-strict, laziness, call-by-need etc

Ленивость — это когда однажды вычисленный узел при повторном запросе вернёт это уже вычисленное значение, а не будет его вычислять заново. Klapaucius об этом сказал более подробно чуть ниже по треду.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 08:50
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Нет, не будет. Будет сгенерирован автомат, который никуда ничего не сохраняет. У этого, кстати, понятные преимущества и недостатки. Чтобы ленивая последовательность считалась один раз ее нужно обернуть во что-то вроде


поскипал.. в общем это то о чём и говорит Quintanar — для получения лени надо постараться А о про сайд-эффекты, преимущества/недостатки понятно, я всего лишь хотел показать, что писанина всё таки нужна, ты мне помог, спасибо.

L>>Так сработает?


K>Так не сработает. А так сработает:


А ну да.. Проклятый китайский метод
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 08:50
Оценка:
Здравствуйте, VladD2, Вы писали:

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


L>>Может быть. Можно посмотреть реализацию ленивого map'а для ленивого списка?


VD>Немерле-версия:


Немерле то как раз понятно, спасибо. Речь шла о С#.
Собственно, я отвечал на вот это замечание AndreiF

Какая еще писанина? В C#, например, всё делается очень просто и ненапряжно.

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 08:50
Оценка: -1
Здравствуйте, VladD2, Вы писали:

К>>Но согласись, что любая ненулевая писанина — это больше и сложнее, чем нулевая


VD>Дело в том, что фактическая писанина остается в библиотеке.


Да не остаётся она в библиотеке. Ты же видел, что для любой новой ленивой функции, использующей лень приходится писать заново её поддержку. Т.е. представь, что у тебя есть Map, есть Filter, есть какая то входная ленивая последовательность, которую тебе надо преобразовать, а потом выбрать из неё определённые значения — опять приходится руками реализовывать лень.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Ленивость или Энергичность по умолчанию?
От: Klapaucius  
Дата: 20.02.07 13:43
Оценка:
Здравствуйте, lomeo, Вы писали:

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


Ну так это понятно. Вобщем-то лени в C# нет, но ее никто и не обещал. Non-strict — есть. Собственно, тут все дело в несогласованной терминологии.
А в Haskell писанина для того, чтобы была семантика non-strict, но не lazy, что, не нужна?

L>>>Так сработает?

K>>Так не сработает. А так сработает:
L>А ну да.. Проклятый китайский метод

Что-что, простите?
... << RSDN@Home 1.2.0 alpha rev. 655>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[12]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 13:58
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Ну так это понятно. Вобщем-то лени в C# нет, но ее никто и не обещал. Non-strict — есть. Собственно, тут все дело в несогласованной терминологии.


Обещал, но, наверное, дело в терминологии, да.

K>А в Haskell писанина для того, чтобы была семантика non-strict, но не lazy, что, не нужна?


А когда это нужно? Кроме ввод-вывода ничего в голову не идёт, но для них лучше strict, имхо. Сайд-эффекты? Типа есть объект от него берём нон-стрикт поток, потом объект меняем и поток тоже должен поменяться? Ну так это будет другой параметр, так что вроде тоже ленью обходимся.

С другой стороны, допустим, всё же нужно. Допустим, в Хаскеле для этого нужна писанина. Только мы же не это обсуждаем. Основной тезис — что такого хорошего в лени по дефолту, на итераторах можно сделать тоже самое без писанины, или мы о другом?

L>>А ну да.. Проклятый китайский метод


K>Что-что, простите?


Копипаст
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 14:19
Оценка: :)))
Здравствуйте, VladD2, Вы писали:

VD>И в том, что "нулевая писанина" в Хаскеле в реальной жизни вылевается в тормоза и проблемы на ровном месте. В общем, ленивость по умолчанию — это не для реальной жизни.


Безосновательная ложь.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[13]: Ленивость или Энергичность по умолчанию?
От: Klapaucius  
Дата: 20.02.07 14:33
Оценка:
Здравствуйте, lomeo, Вы писали:

K>>А в Haskell писанина для того, чтобы была семантика non-strict, но не lazy, что, не нужна?

L>А когда это нужно?

Это не серьезно. Вот человек, который на шарпе пишет постоянно, а на хаскеле не писал может запросто спростить "А когда это нужно?" про lazy, если у него есть non-strict. Собственно, эта тема показывает, что разница вообще не для всех очевидна.

L>Кроме ввод-вывода ничего в голову не идёт, но для них лучше strict, имхо.


Ну ну. Как будто этого мало. Получить какой-нибудь несколькогиговый файл как non-strict последовательность строк или там блоков удобно. А в память его поднимать совершенно не нужно, и в данном случае, то, что при повтороном обращении к последовательности она будет пересчитываться уже не баг, а фича.

L>Сайд-эффекты? Типа есть объект от него берём нон-стрикт поток, потом объект меняем и поток тоже должен поменяться? Ну так это будет другой параметр, так что вроде тоже ленью обходимся.

L>С другой стороны, допустим, всё же нужно. Допустим, в Хаскеле для этого нужна писанина. Только мы же не это обсуждаем.

Не знаю, что Вы обсуждаете, а мы обсуждаем именно это.

L>Основной тезис — что такого хорошего в лени по дефолту, на итераторах можно сделать тоже самое без писанины, или мы о другом?


Собственно, мой вопрос ясен. Я ничего про "тоже самое" не говорил. Я попросил продемонстрировать как non-strict выглядит на Haskell — только и всего. Я считаю, что к теме разговора это имеет непосредственное отношение.
... << RSDN@Home 1.2.0 alpha rev. 655>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[14]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 14:52
Оценка:
Здравствуйте, Klapaucius, Вы писали:

L>>С другой стороны, допустим, всё же нужно. Допустим, в Хаскеле для этого нужна писанина. Только мы же не это обсуждаем.


K>Не знаю, что Вы обсуждаете, а мы обсуждаем именно это.


AndreiF спрашивал зачем нужен lazy по дефолту, если его можно сделать на итераторах. Мы о разном?

L>>Основной тезис — что такого хорошего в лени по дефолту, на итераторах можно сделать тоже самое без писанины, или мы о другом?


K>Собственно, мой вопрос ясен. Я ничего про "тоже самое" не говорил. Я попросил продемонстрировать как non-strict выглядит на Haskell — только и всего. Я считаю, что к теме разговора это имеет непосредственное отношение.


Ну, хорошо, хорошо, если Вы так считаете, нет проблем. Меня просто сбила с толку смена темы.

Чтение лога из файла — это именно IO. IO в Хаскеле сделано на акциях. Акции — внутри ленивые сами по себе, но из-за того, что им передаётся дополнительный параметр — realworld — они превращаются в non-strict, т.е. вычисляются заново по запросу. Realworld — параметр невидимый для программиста, т.е. когда мы пишем

do line <- getLine
   doSomething line


то в getLine передаётся этот параметр, таким образом, функцию надо будет вычислить заново при следующем обращении. Замечу, что на производительности этот параметр не сказывается — так как он не используется, то он просто удаляется из скомпилированного кода. Таким образом для программиста всё это прозрачно — вот функция primes — она возвращает поток простых чисел и она ленива, а вот функция getLine — она возвращает строку, введённую пользователем, и она non-strict, но не ленива.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 14:59
Оценка:
Здравствуйте, AndreiF, Вы писали:

Q>>Ваши итераторы — суть костыли, писанина лишняя все равно нужна.


AF>Какая еще писанина? В C#, например, всё делается очень просто и ненапряжно.


А вот ещё! Тут понял, что итераторы — это только ленивые списки. Поправь меня, если я не прав. Если я прав, то вся остальная ленивость делается непросто и напряжно
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Ленивость или Энергичность по умолчанию?
От: deniok Россия  
Дата: 20.02.07 15:28
Оценка:
Здравствуйте, Klapaucius, Вы писали:

Я что-то запутался в этой подветке.
Немножко Хаскелла:
ones :: [Integer]
ones = 1 : ones -- бесконечный список единиц

f :: Integer -> Integer -- реализация не важна

dummy :: Integer -> Integer -> [Integer] -> Integer 
dummy  a b [] = a - b -- для пустого списка вычитаем
dummy  a b _  = a + b -- в остальных случаях складываем


При вызове dummy 3 2 ones вернёт 1 — это ленивость, как я её понимаю. Вычисляется только то, что нужно для дальнейших вычислений. То, что третий, списочный аргумент имеет значение _|_ меня (и Хаскелл) не волнует ни разу.

При вызове dummy (f 5) (f 5) [1,2,3] — это ленивость, как она здесь обсуждается, то есть f 5 вычисляется только 1 раз. Но, по-моему, это — оптимизация, допустимая как естественное следствие чистоты языка.

При вызове dummy (f 5) (f 15) [1,2,3] — порядок вычислений f 5 и f 15 неопределён. Это нестрогость, как я её понимаю.

Где я неправ?
Re[8]: Ленивость или Энергичность по умолчанию?
От: EvilChild Ниоткуда  
Дата: 20.02.07 18:04
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Дело в том, что фактическая писанина остается в библиотеке.

VD>И в том, что "нулевая писанина" в Хаскеле в реальной жизни вылевается в тормоза и проблемы на ровном месте. В общем, ленивость по умолчанию — это не для реальной жизни.

Можно подробнее о

"нулевая писанина" в Хаскеле в реальной жизни вылевается в тормоза и проблемы на ровном месте

?
now playing: Noisia — The Flow
Re[7]: Ленивость или Энергичность по умолчанию?
От: EvilChild Ниоткуда  
Дата: 20.02.07 18:08
Оценка:
Здравствуйте, lomeo, Вы писали:

L>А вот ещё! Тут понял, что итераторы — это только ленивые списки. Поправь меня, если я не прав. Если я прав, то вся остальная ленивость делается непросто и напряжно


Именно так, а всё остальное вручную
now playing: Corrupt Souls — Broadcast
Re[9]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.02.07 21:11
Оценка: -1
Здравствуйте, EvilChild, Вы писали:

EC>Можно подробнее о

EC>

EC>"нулевая писанина" в Хаскеле в реальной жизни вылевается в тормоза и проблемы на ровном месте

EC>?

А что подробнее то? Скачай кмпилятор и попробуй написать реальную программу. Увидишь, что все совсем не так как описывают это дело фанаты.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Ленивость или Энергичность по умолчанию?
От: Andy Panda США  
Дата: 21.02.07 07:49
Оценка:
Здравствуйте, EvilChild, Вы писали:

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


VD>>Дело в том, что фактическая писанина остается в библиотеке.

VD>>И в том, что "нулевая писанина" в Хаскеле в реальной жизни вылевается в тормоза и проблемы на ровном месте. В общем, ленивость по умолчанию — это не для реальной жизни.

EC>Можно подробнее о

EC>

EC>"нулевая писанина" в Хаскеле в реальной жизни вылевается в тормоза и проблемы на ровном месте

EC>?

Любимый маразм здесь

15 комментариев, которые показывают объезды вместо нормального пути.
... << RSDN@Home 1.2.0 alpha rev. 648>>
Re[11]: Ленивость или Энергичность по умолчанию?
От: deniok Россия  
Дата: 21.02.07 11:40
Оценка:
Здравствуйте, deniok, Вы писали:

D>При вызове dummy (f 5) (f 15) [1,2,3] — порядок вычислений f 5 и f 15 неопределён. Это нестрогость, как я её понимаю.


D>Где я неправ?


Сам себе отвечаю: здесь и неправ! Писал на бегу и сморозил глупость.
Re[15]: Ленивость или Энергичность по умолчанию?
От: Klapaucius  
Дата: 21.02.07 13:05
Оценка: +1
Здравствуйте, lomeo, Вы писали:

L>AndreiF спрашивал зачем нужен lazy по дефолту, если его можно сделать на итераторах. Мы о разном?


Я не разделяю его точку зрения. Итераторы это non-strict списки strict значений. Они действительно делаются легко.
Lazy или non-strict значение с помощью итераторов, естественно, не сделать. Они делаются с помощью делегатов и анонимных методов.

L>>>Основной тезис — что такого хорошего в лени по дефолту, на итераторах можно сделать тоже самое без писанины, или мы о другом?

K>>Собственно, мой вопрос ясен. Я ничего про "тоже самое" не говорил. Я попросил продемонстрировать как non-strict выглядит на Haskell — только и всего. Я считаю, что к теме разговора это имеет непосредственное отношение.

L>Чтение лога из файла — это именно IO. IO в Хаскеле сделано на акциях. Акции — внутри ленивые сами по себе, но из-за того, что им передаётся дополнительный параметр — realworld — они превращаются в non-strict, т.е. вычисляются заново по запросу. Realworld — параметр невидимый для программиста, т.е. когда мы пишем


L>
L>do line <- getLine
L>   doSomething line
L>


L>то в getLine передаётся этот параметр, таким образом, функцию надо будет вычислить заново при следующем обращении. Замечу, что на производительности этот параметр не сказывается — так как он не используется, то он просто удаляется из скомпилированного кода. Таким образом для программиста всё это прозрачно — вот функция primes — она возвращает поток простых чисел и она ленива, а вот функция getLine — она возвращает строку, введённую пользователем, и она non-strict, но не ленива.


То, как делается в Haskell non-strict значение я знаю. Я спрашивал о том, как в Haskell сделать non-strict список strict значений.
Другими словами, я представляю как посчитать количество символов в файле на Haskell выделяя O(N) памяти.
Как-то так:
readAndCount filePath = bracket (openFile filePath ReadMode) hClose
    (\handle -> do
        chars <- hGetContents handle
        putStrLn $ show $ length chars
    )

Представте, что я тормоз и напишите код, который решает ту же самую задачу, выделяя O(1) памяти.

Возвращаясь к теме разговора — не ленивые значения в Haskell реализуются с помощью контейнеров, так? Ну в таком случае ситуация по большому счету симметрична. Ведь в C# можно сделать с помощью контейнеров ленивые значения.

Lazy<int> lint = Lazy<int>(delegate(){ return foo.CalcInt(); }); //тут ничего не считается.

lint = lint.Apply(delegate(int i){ return i + 2; }); // и здесь ничего еще не считается.

lint = lint.Apply(delegate(int i){ return i * 7; }); 
// все еще ничего. Где-то внутри lint продолжает расти очередь делегатов, 
// а может быть работает emit - это все детали реализации.
// еще Lazy<int> может быть футурой и вычисляться в другом потоке, например.

int i = lint.Value; // вот тут оно все и посчиталось.


Кстати, Lazy<T> может быть даже — ха-ха — монадой.
Теперь ленивый, а не non-strict Map
IEnumerable<Lazy<RT>> Map<T, RT>(IEnumerable<Lazy<T>> seq, Func<T, Lazy<RT>> fun)
{
    foreach(Lazy<T> elem in seq) yield return elem.Bind(fun);
}


Ассиметрия тут заключается не в том, что где-то что-то по умолчанию, а вот в чем:
1) В Haskell система типов мощнее и там такие вещи реализуются лучше.
2) В C# нет для этого сахара и поэтому будет адскiй сiнтаксiчъскiй овърхедъ.
3) В C# ничего такого в стандартной библиотеке нет, но это уже состязание стандартных библиотек, а не языков.

При равных выразительных возможностях весь этот спор не стоит и выеденного яйца — понятно, что в языке со strict по умолчанию нужно реализовывать lazy и наоборот. Тут все дело в том, что используется чаще, lazy или strict.
... << RSDN@Home 1.2.0 alpha rev. 655>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[11]: Ленивость или Энергичность по умолчанию?
От: R.K. Украина  
Дата: 21.02.07 16:26
Оценка: +1
Здравствуйте, deniok, Вы писали:

D>При вызове dummy 3 2 ones вернёт 1 — это ленивость, как я её понимаю. Вычисляется только то, что нужно для дальнейших вычислений. То, что третий, списочный аргумент имеет значение _|_ меня (и Хаскелл) не волнует ни разу.


Третий аргумент тут совсем не боттом.

D>При вызове dummy (f 5) (f 5) [1,2,3] — это ленивость, как она здесь обсуждается, то есть f 5 вычисляется только 1 раз. Но, по-моему, это — оптимизация, допустимая как естественное следствие чистоты языка.


В данном случае компилятор может не соптимизировать второе вычисление (f 5), лучше делать так: let f5 = f 5 in dummy f5 f5 [1,2,3]. Тогда f5 будет точно представлять одно вычисление.
You aren't expected to absorb this
Re[10]: Ленивость или Энергичность по умолчанию?
От: EvilChild Ниоткуда  
Дата: 21.02.07 17:09
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>А что подробнее то? Скачай кмпилятор и попробуй написать реальную программу. Увидишь, что все совсем не так как описывают это дело фанаты.

Это прикол такой? Если да, то мне не удалось его оценить.
Так можно любой инструмент забраковать.
now playing: Future Prophecies — Eastern Organic
Re[12]: Ленивость или Энергичность по умолчанию?
От: deniok Россия  
Дата: 21.02.07 17:16
Оценка:
Да, спасибо, этот пост по количеству неточностей и ошибок — просто кошмар. На меня нашло умопомрачение
Re[10]: Ленивость или Энергичность по умолчанию?
От: EvilChild Ниоткуда  
Дата: 21.02.07 17:18
Оценка: -2 :)
Здравствуйте, Andy Panda, Вы писали:

AP>Любимый маразм здесь


AP>15 комментариев, которые показывают объезды вместо нормального пути.


Моё мнение такое — человек не освоился с инструментом и пользовался им неправильно (так как привык пользоваться другими), это не сработало, ему показали как правильно. Т.е. каждому инструменту свой подход и круг решаемых задач. А нормальность понятие относительное.
now playing: Future Prophecies — Eastern Organic
Re[7]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 22.02.07 04:59
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Если я прав, то вся остальная ленивость делается непросто и напряжно


Какая именно и что она дает?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 22.02.07 04:59
Оценка:
Здравствуйте, lomeo, Вы писали:

L>

L>Какая еще писанина? В C#, например, всё делается очень просто и ненапряжно.


Значит, просто неправильно понял, что в Хаскелле называется ленивостью. Правда, остается один вопрос — а зачем это вообще нужно на практике?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Ленивость или Энергичность по умолчанию?
От: deniok Россия  
Дата: 22.02.07 07:32
Оценка:
AP>Любимый маразм здесь

AP>15 комментариев, которые показывают объезды вместо нормального пути.


А каков "нормальный путь" при работе с контейнером, не влезающим в стек?
Re[8]: Ленивость или Энергичность по умолчанию?
От: deniok Россия  
Дата: 22.02.07 08:04
Оценка: -1
Здравствуйте, AndreiF, Вы писали:

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


L>>Если я прав, то вся остальная ленивость делается непросто и напряжно


AF>Какая именно и что она дает?


Те же фокусы, что и со списками, с деревьями и, шире, с любыми рекурсивными типами данных. Как ещё один пример.
Re[2]: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 22.02.07 09:59
Оценка: 14 (3) +2
VladD2,

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


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

У меня есть кой-какой материал — примеры различной сложности, самые существенные выдержки из мнений разных товарищей (в т.ч. Вадлера, Хьюггса и других). Могу попробовать оформить в виде статьи, если ты не против. Нужна?
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[16]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.02.07 11:00
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Я не разделяю его точку зрения. Итераторы это non-strict списки strict значений. Они действительно делаются легко.

K>Lazy или non-strict значение с помощью итераторов, естественно, не сделать. Они делаются с помощью делегатов и анонимных методов.

Собственно об этом я и говорил.

K>То, как делается в Haskell non-strict значение я знаю. Я спрашивал о том, как в Haskell сделать non-strict список strict значений.


Не понял

K>Представте, что я тормоз и напишите код, который решает ту же самую задачу, выделяя O(1) памяти.


hFileSize? Делается точно также как и везде. В цикле читается буфер пока-не-EOF.
Я не понимаю, к чему этот пример?

K>Возвращаясь к теме разговора — не ленивые значения в Haskell реализуются с помощью контейнеров, так? Ну в таком случае ситуация по большому счету симметрична.


Согласен.

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


Согласен.

K>Тут все дело в том, что используется чаще, lazy или strict.


Зависит от задач, имхо.

Мы вообще о чем говорим? С чем Вы не согласны из того, что я сказал?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.02.07 11:00
Оценка:
Здравствуйте, AndreiF, Вы писали:

AF>Значит, просто неправильно понял, что в Хаскелле называется ленивостью. Правда, остается один вопрос — а зачем это вообще нужно на практике?


Каждому своё — мне ленивость позволяет кратко записывать код. Примеров можно привести массу. Общий пример такой: когда я пишу код на eager языке, я вынужден учитывать то, будет ли использоваться это вычисление дальше 100% или нет и в зависимости от этого делать декомпозицию. Ленивость позволяет не усложнять код переносом значений, необходимых для вычисления на всю длину цепочки вызовов, а сразу записать это вычисление. Т.е. это аналог передачи объекта, эмулирующего ленивое вычисление, по цепочке и вызов в нужном месте его метода, который и делает это вычисление. При ленивости эта обертка в коде не нужна. Ещё сильный пример — это ленивые структуры данных. Работая с ними нет нужды задумываться об их конечности, например, значение подставит тебе нужное плечо в нужное время, а описываешь ты это так, как будто работаешь с обычными данными, удобно. Ну, а зачем нужен удобный язык на практике, думаю, рассказывать не надо

Не хочу тебя обидеть, но мне кажется, что ты задаёшь эти вопросы не с целью узнать зачем нужна ленивость, а чтобы поспорить о её необходимости. Очень надеюсь, что я ошибаюсь.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.02.07 11:10
Оценка: +1 -1
Здравствуйте, AndreiF, Вы писали:

L>>Если я прав, то вся остальная ленивость делается непросто и напряжно


AF>Какая именно и что она дает?


Что даёт, я только что писал в ответе на другой твой пост.

Какая именно — например, calc1(calc2, calc3), где calc2 и calc3 — определённые вычисления, например x + 3, или doSomething(y) Ну для этого примера, правда, писанины нужно совсем немножко, но она нужна, из-за чего теряется лёгкость, присущая ленивому коду — когда мы пишем на ленивом языке ленивые вещи, мы об этом не думаем. Мы ведь обсуждаем этот момент?

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

Если короче, то ленивость вносит свою лепту в повышение декларативности кода.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Ленивость или Энергичность по умолчанию?
От: deniok Россия  
Дата: 22.02.07 11:51
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>У меня есть кой-какой материал — примеры различной сложности, самые существенные выдержки из мнений разных товарищей (в т.ч. Вадлера, Хьюггса и других). Могу попробовать оформить в виде статьи, если ты не против. Нужна?


Однозначно!
Re[11]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 22.02.07 12:34
Оценка:
Здравствуйте, lomeo, Вы писали:

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


Мне просто интересно. Можно какой-нибудь практический пример, где ленивость сильно упрощает жизнь?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[12]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.02.07 14:34
Оценка: 3 (1)
Здравствуйте, AndreiF, Вы писали:

AF>Мне просто интересно. Можно какой-нибудь практический пример, где ленивость сильно упрощает жизнь?


Такого примера у меня нет, потому что "сильно упрощает", это, наверное, не то слово. Ленивость позволяет использовать другие идиомы и паттерны при построении программы. Ключевое слово — "другие".

Пример идиом — итераторы в неленивой программе / списки в ленивой. Списки по мне гораздо проще итераторов при той же функциональности.

Основное, что мне нравится — это декларативность программы. Вычисление в ленивой программе выглядит в коде как вычисление, но является значением. Это сильно повышает декларативность конструкции. Без ленивости по умолчанию это пришлось бы объявлять явно. А так, просто пишем

doLoooongCalculation `ifFails` doOtherLooooongCalculation


Представь, что мы делаем трансформацию над какими то данными, а потом получаем подгруппу трансформированных данных по каким то его свойствам. Т.е. простой filter/map. Представь, что трансформированные данные "тяжелые". Ленивость позволяет вычислять только нужную их часть — необходимую для проверки — попадут ли они в выходную подгруппу или нет. Без ленивости мы бы добавили дополнительный код проверки, зависящий от первоначальных данных, с ленивостью этого не нужно — мы работаем с данными так, как будто они трансформированы полностью. Да и потом, если мы используем только часть этих объектов, то именно она и будет вычислена, и нам не надо заботиться о создании более лёгкого объекта — аналога тяжёлого, но с меньшим количеством полей. Не знаю, повышение ли это декларативности, но код здесь короче. Немного, но короче.

-- ну ка, поглядим сколько монет в сундуках мертвеца, лежащих в трюмах с награбленным.
sum $ map coins $ filter (\chest -> owner chest == deadMan) $ concatMap chests treasures


Мне кажется, что ОО получило популярность также и в силу его декларативности. В частности, объявления классов явно декларативно. Ленивость решает часть проблем решаемых ОО, не меняя код. Нет нужды в организации делегатов, в передаче объекта, несущего набор параметров в своих полях, для того, чтобы позже позвать его метод. Достаточно просто передать само вычисление.

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

[]     ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)


И потом, когда получаем первые 5 элементов склеенного списка мы можем быть уверенными, что склейки не произойдёт, т.к. первый список содержит больше 5-и элементов. Либо произойдёт склейка только с нужным куском второго списка. Нам не надо об этом задумываться — мы просто получаем первые элементы так, как будто полная склейка произошла на самом деле. И здесь код короче уже намного.

Ленивость — не единственная и не самая важная составляющая декларативного подхода, здесь важен комплекс, но с ней некоторые вещи делаются проще.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 22.02.07 14:41
Оценка: 42 (4)
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Практически, однако, вопрос о соотношении

LCR>1) дефолтной ленивости с опциональной энергичностью и анализатором энергичности (strictness analyser) как в Хаскелле, и
LCR>2) дефолтной энергичностью с опциональной ленивостью (как в Ocaml, Scala, N, etc)
LCR>остаётся открытым и требует особого обсуждения.

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

Для явной (опциональной) ленивости — интересен более общий подход с фьючерсами, который дает не только ленивость, но и много других полезностей. Это, мне кажется, то, что нужно. Примерно как тут: http://www.ps.uni-sb.de/alice/manual/futures.html
Re[2]: Ленивость или Энергичность по умолчанию?
От: Курилка Россия http://kirya.narod.ru/
Дата: 22.02.07 14:46
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Для явной (опциональной) ленивости — интересен более общий подход с фьючерсами, который дает не только ленивость, но и много других полезностей. Это, мне кажется, то, что нужно. Примерно как тут: http://www.ps.uni-sb.de/alice/manual/futures.html


А почему именно Alice? Вон в Scala тоже фьючерсы есть.
Re[3]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 22.02.07 14:56
Оценка:
Здравствуйте, Курилка, Вы писали:

G>>Для явной (опциональной) ленивости — интересен более общий подход с фьючерсами, который дает не только ленивость, но и много других полезностей. Это, мне кажется, то, что нужно. Примерно как тут: http://www.ps.uni-sb.de/alice/manual/futures.html


К>А почему именно Alice? Вон в Scala тоже фьючерсы есть.


Мне, собственно, сама идея фьючерсов как обобщения отложенных вычислений нравится — неважно, в каком языке.
А Scala — очень симпатичный язычок.
Re[3]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.02.07 16:59
Оценка: -1
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Недостатки (вернее, недостаток) сегодняшних ленивых языков автоматически переносить на ситуацию в целом... на мой взгляд неправильно. Да, сегодняшние ленивые языки довольно несовершенны. Но у ленивости тоже есть положительные моменты.


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

LCR>У меня есть кой-какой материал — примеры различной сложности, самые существенные выдержки из мнений разных товарищей (в т.ч. Вадлера, Хьюггса и других). Могу попробовать оформить в виде статьи, если ты не против. Нужна?


Мнения не нужны. У меня есть свое основанное на личном опыте. Нужны те навороченые технологии которые позволят превратить эту игрушку в действительно удобную технолгию.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.02.07 16:59
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Каждому своё — мне ленивость позволяет кратко записывать код.


А я справляюсь и без нее.

L>Примеров можно привести массу.


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

L> Общий пример такой: когда я пишу код на eager языке, я вынужден учитывать то, будет ли использоваться это вычисление дальше 100% или нет и в зависимости от этого делать декомпозицию. Ленивость позволяет не усложнять код переносом значений, необходимых для вычисления на всю длину цепочки вызовов, а сразу записать это вычисление.


Ленивость тут не причем. Ты просто работаешь с динамически формируемым списком. К тому же, обратная старона этого невозможность просто записать эффективные алгоритмы требующие индексированного доступа.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.02.07 16:59
Оценка: -1
Здравствуйте, lomeo, Вы писали:

L>Такого примера у меня нет, потому что "сильно упрощает", это, наверное, не то слово. Ленивость позволяет использовать другие идиомы и паттерны при построении программы. Ключевое слово — "другие".


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

ЗЫ

В общем, это сотрясение воздуха и попытка раздуть слона из мухи.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.02.07 16:59
Оценка:
Здравствуйте, deniok, Вы писали:

AP>>Любимый маразм здесь


AP>>15 комментариев, которые показывают объезды вместо нормального пути.


D>А каков "нормальный путь" при работе с контейнером, не влезающим в стек?


А то что продемонстрировал автор той темы. Просто вызвать функцию len которая обязана в ленивом языке выполняться лениво.

Какого черта весь из себя неленивый C# в такой ситуации ведет себя нормально и не требует костылей, а крутой спер-яызк пасует?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Ленивость или Энергичность по умолчанию?
От: EvilChild Ниоткуда  
Дата: 22.02.07 17:25
Оценка: -2
Здравствуйте, VladD2, Вы писали:

VD>Какого черта весь из себя неленивый C# в такой ситуации ведет себя нормально и не требует костылей, а крутой спер-яызк пасует?


Это из серии с какого такого я должен в C сам управлять памятью. Настолько же корректная претензия.
now playing: Future Prophecies — Dark matter
Re[13]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.02.07 18:10
Оценка:
Здравствуйте, EvilChild, Вы писали:

VD>>Какого черта весь из себя неленивый C# в такой ситуации ведет себя нормально и не требует костылей, а крутой спер-яызк пасует?


EC>Это из серии с какого такого я должен в C сам управлять памятью. Настолько же корректная претензия.


Я настолько обескуражен бессмысленностью твоих слов, что даже незнаю что и ответить то.
Я не вижу тут никакой связи с ручным управлением памятью в частности и с С в целом.
Я вижу что примитивный пример на Хаскеле который должен был бы работать как часы не работает. И под это пытаются подвести заумную базу. В то же время, точно такой же код на C# будет работать как часы. Причем он будте точно так же ленив. Причем тут С и выделение памяти я понять немогу.

Это чистейшей воды глюк компилятора или (что еще хуже) идеологический ляп.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Ленивость или Энергичность по умолчанию?
От: EvilChild Ниоткуда  
Дата: 22.02.07 18:50
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я настолько обескуражен бессмысленностью твоих слов, что даже незнаю что и ответить то.

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

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

VD>Я вижу что примитивный пример на Хаскеле который должен был бы работать как часы не работает.


Я неоднократно видел как люди не имеющие опыта работы с реляционными БД начинали во всю использовать курсоры в хранимках MS SQL и при этом сильно удивлялись тормозности получаемого решения — типа я же так на VB/Delphi/C++ пишу и всё шуршит, а тут, что за хрень?
Для них это тоже выглядит как неудовлетворительная работа самых простых и очевидных (для них) способов решения задачи.

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

Надеюсь сейчас понятнее изложил мысль или опять безсмысленный набор слов?
now playing: Future Prophecies — Dark matter
Re[4]: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 22.02.07 19:17
Оценка:
VladD2,

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


"Ваш "форд" может быть любого цвета, при условии что этот цвет — чёрный".

VD>Мнения не нужны. У меня есть свое основанное на личном опыте.


Хорошо, можешь привести своё мнение, когда ленивость по умолчанию имеет преимущество? Я разумеется, добавлю его (мнение) в свою копилку, при условии что оно не попадалось ранее (на рсдн почему-то не любят бояны)
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 22.02.07 19:17
Оценка: +2
Gaperton,

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

Зато за поддержание чистоты в грязном мире заботится компилятор, а не программистские головы и жопы. Ну и специально для тех, кто привык программировать спинным мозгом, можно вывесить плакат с большой надписью "ДЕЛАЙ ТАК". Короче, здесь банальная разница в точках зрения.

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

Согласен, и это вычёркивает Хаскелл из целого ряда задач. Но там уже такая толкотня, что прямо скажем, невелика потеря

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

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

G>Для явной (опциональной) ленивости — интересен более общий подход с фьючерсами, который дает не только ленивость, но и много других полезностей. Это, мне кажется, то, что нужно. Примерно как тут: http://www.ps.uni-sb.de/alice/manual/futures.html


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

Да, и это может быть реализовано на монадах.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[15]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.02.07 23:03
Оценка:
Здравствуйте, EvilChild, Вы писали:

EC>Ок, поясняю, что имел в виду:

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

Где ты узрел в этой подветке сетование на линивость? Проблема в данном примере не в линивости. А в кривости. В том, что эта ленивость не работает в соврешенно банальном случае.

EC>Аналогия с C состоит в следующем:

EC>в C ты обязан управлять памятью сам, это фундаментальное свойство языка, поэтому странно на это жаловаться программируя на C.
EC>Аналогия ясна?

Ясна. Точнее ясно, что она не к месту.

VD>>Я вижу что примитивный пример на Хаскеле который должен был бы работать как часы не работает.


EC>Я неоднократно видел как люди не имеющие опыта....


Какой к черту опыт? Пример примитивен и очевиден!

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

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

Здорово, здорово. Но не для этой жизни.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.02.07 23:03
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Хорошо, можешь привести своё мнение, когда ленивость по умолчанию имеет преимущество?


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

LCR> Я разумеется, добавлю его (мнение) в свою копилку, при условии что оно не попадалось ранее (на рсдн почему-то не любят бояны)


Растрою тебя. Меня не тешит то, что мое мнение может попасть в твою копилку.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.02.07 23:03
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Зато за поддержание чистоты в грязном мире заботится компилятор, а не программистские головы и жопы. Ну и специально для тех, кто привык программировать спинным мозгом, можно вывесить плакат с большой надписью "ДЕЛАЙ ТАК". Короче, здесь банальная разница в точках зрения.


Причина любого спора "банальная разница в точках зрения". Это ты конечно сильно сказал.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 23.02.07 12:36
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Gaperton,


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

LCR>Зато за поддержание чистоты в грязном мире заботится компилятор, а не программистские головы и жопы. Ну и специально для тех, кто привык программировать спинным мозгом, можно вывесить плакат с большой надписью "ДЕЛАЙ ТАК". Короче, здесь банальная разница в точках зрения.

О поддержании чистоты может позаботится компилятор и в грязном языке, если вы введете модификатор pure (или наоборот — dirty ) для функций. В этом случае компилятор проверит и докажет чистоту.

Монадный ввод-вывод не сильно будет отличаться по сути — монады точно так же "заражают" код, и выглядит он все равно императивно. В любом случае будет разумно отделить одно от другого, нет? Так в чем реальная разница?

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

LCR>Согласен, и это вычёркивает Хаскелл из целого ряда задач. Но там уже такая толкотня, что прямо скажем, невелика потеря

Угу, а что остается? Назовите полезные, не академические задачи, где Хаскель рвет всех. А то на пустом множестве, сами понимаете, доказать можно все что угодно — на нем верно все.

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


Семантическая простота . Вы в состоянии рассчитать асимптотическую сложность и расход памяти для ленивой программы большого объема, особенно если над кодом поработал strictness analyzer? Это у нас семантическая простота называется (не, ну я понимаю, бета-преобразование, амфибрахий там, то, се...)?

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


Какие конкретно техники и грабли он не должен за собой тащить?

G>>Для явной (опциональной) ленивости — интересен более общий подход с фьючерсами, который дает не только ленивость, но и много других полезностей. Это, мне кажется, то, что нужно. Примерно как тут: http://www.ps.uni-sb.de/alice/manual/futures.html


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


А для Хаскеля у нас автоматических распараллеливателей дофига, да? Кстати, фортрановские и сишные программы уже давно параллелят автоматически — это например интеловские компиляторы умеют.

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

LCR>К тому же забота о независимости отщипываемых вычислений от основных на кого ложится? По сравнению с традиционными деревянными потоками это разумеется супер-гипер, но на светлое будущее (упс, коламбур) не тянет.


А что у нас тянет на светлое будущее? Забота о независимости вычислений всегда ложится на программиста.

LCR>Да, и это может быть реализовано на монадах.


Ну мало-ли, что может быть реализовано на монадах.
Re[14]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 24.02.07 11:46
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>Такого примера у меня нет, потому что "сильно упрощает", это, наверное, не то слово. Ленивость позволяет использовать другие идиомы и паттерны при построении программы. Ключевое слово — "другие".


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


Обратное тоже справедливо, и?

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


Меня спросили — я ответил. Если ты с чем то не согласен, озвучь это. А то непонятно зачем ты всё это пишешь.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 24.02.07 13:28
Оценка: 10 (2) +1
Gaperton,

LCR>>Зато за поддержание чистоты в грязном мире заботится компилятор, а не программистские головы и жопы. Ну и специально для тех, кто привык программировать спинным мозгом, можно вывесить плакат с большой надписью "ДЕЛАЙ ТАК". Короче, здесь банальная разница в точках зрения.


G>О поддержании чистоты может позаботится компилятор и в грязном языке, если вы введете модификатор pure (или наоборот — dirty) для функций. В этом случае компилятор проверит и докажет чистоту.


G>Монадный ввод-вывод не сильно будет отличаться по сути — монады точно так же "заражают" код, и выглядит он все равно императивно. В любом случае будет разумно отделить одно от другого, нет? Так в чем реальная разница?


Таак, ты (можно на "ты"?) наступил на ту же самую граблю, искры от удара которой я имел возможность лицезреть здесь
Автор: Last Cjow Rhrr
Дата: 08.02.07
. Если немного подумать, то окажется, что

1. грязь бывает очень разная — то есть грязь имеет тип.
2. часто хочется выполнить грязный код внутри чистого — а это значит, что все проверки компилятора накрываются медным тазом.
3. монадические значения — это обычные значения. Их можно сохранять в коллекциях, частично выполнять, передавать в ФВП, (де)сериализовывать и прочее. Их нужно только выполнять в нужном контексте и об этом следит система типов. Что может предложить 'dirty' в качестве ответа?
4. если идти дальше, то модификатор dirty должны иметь не только функции, но типы параметров в таких функциях как map. То есть
map      :: dirty(a -> b) -> [a] -> [b ]
map_pure :: (a -> b) -> [a] -> [b ]

должны рассматриваться как разные функции и тогда каждую функцию нужно реализовывать в 2х экземплярах, а это не может не напрягать. Либо надо обеспечить преобразование чистой функции в грязную ( изобрели лифтинг). Теперь предположим мы проектируем какой-нибудь общий интерфейс — нам придётся повсюду воткнуть туда dirty, мы же не хотим проблем в будущем... И где теперь поддержка компилятора?
5. и как избежать транзитивного замыкания грязи, когда у нас 99.9% функций становятся грязными лишь потому, что мы где-то в глубине немножечко замарались?

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

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

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

LCR>>Согласен, и это вычёркивает Хаскелл из целого ряда задач. Но там уже такая толкотня, что прямо скажем, невелика потеря
G>Угу, а что остается? Назовите полезные, не академические задачи, где Хаскель рвет всех. А то на пустом множестве, сами понимаете, доказать можно все что угодно — на нем верно все.
Не надо крайностей. Так получилось, что killer-app пока нет. Однако, Хаскелл применяется в целой куче областей и небезуспешно. Думаю что с помощью чистого нестрогого языка будет возможно строить сверхбольшие системы — это может быть killer-app. Может быть это будет Хаскелл, может Clean, а может быть и Хаскелл-2
А _доказать_ здесь всё равно невозможно ничего, сам понимаешь. Так что в определённый момент нам нужно будет просто остановить наше бодание.

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

Возможность чего-то там рассчитать как раз имеет дело с вычислительной простотой. Семантическая простота — это "копать от забора до обеда, а выбор траектории и формы лопат меня не волнует".

Трудности с расчётами возникают очевидно из-за того, что если у нас f имеет сложность O(N), g имеет сложность O(N^2), то композиция (f . g) совсем необязательно будет иметь сложность O(N^3) как в энергичном языке, а может быть всё, что угодно — от O(N^3) до O(1) — зависит от условий на входные данные. И это я считаю очень интересной особенностью нестрогих языков.

В конце концов,

The physical causality works as follows. The brain issues the orders which propagate sequentially through the nerves, make the articulations and the limbs move, and finally the end effector — the hand — grasps the kettle and put in on the fire. Anybody protests?

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

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


G>Какие конкретно техники и грабли он не должен за собой тащить?


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

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


G>А для Хаскеля у нас автоматических распараллеливателей дофига, да? Кстати, фортрановские и сишные программы уже давно параллелят автоматически — это например интеловские компиляторы умеют.


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

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


Хм. А чем обусловлена такая "невытаскиваемость в принципе"? Или ты априори предполагаешь, что переллелизатор не может быть оформлен в виде библиотеки? Или передать туда информацию кроме как исходный код в принципе невозможно?
На всякий случай, может быть ты не видел:
Параллельный OCaml
Автор: Mirrorer
Дата: 06.02.07
. Вот это шаг в светлое будущее.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[15]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.02.07 23:16
Оценка:
Здравствуйте, lomeo, Вы писали:

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


L>Обратное тоже справедливо, и?


Несомненно. Это вопрос предпочтений в дизайне языка. И на мой взгляд, если язык разрабатывается для реальной жизни (причем, здесь и сейчас), то надо по умолчанию выбирать "энергичнось", а ленивость делать по запросу. Возможно когда-нибудь, когда оптимизация станет очень качественной и доступной всем, все и изменится. Но это время явно еще не настало.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.02.07 00:07
Оценка: -2
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>1. грязь бывает очень разная — то есть грязь имеет тип.


Это довольно бессмысленная мысль.

LCR>2. часто хочется выполнить грязный код внутри чистого — а это значит, что все проверки компилятора накрываются медным тазом.


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

LCR>3. монадические значения — это обычные значения. Их можно сохранять в коллекциях, частично выполнять, передавать в ФВП, (де)сериализовывать и прочее. Их нужно только выполнять в нужном контексте и об этом следит система типов. Что может предложить 'dirty' в качестве ответа?


1. Отсуствие монодического булшита.
2. Простоту модели и реализации.
3. Эффективность исполнения (порождение эффективного кода).

LCR>4. если идти дальше, то модификатор dirty должны иметь не только функции, но типы параметров в таких функциях как map.


Это продолжение монодического, точнее пуританского, образа мысли. На практике никаких таких проблем нет. Достаточно создать некие фунции воде MapLazy и все бдет ОК.

LCR>5. и как избежать транзитивного замыкания грязи, когда у нас 99.9% функций становятся грязными лишь потому, что мы где-то в глубине немножечко замарались?


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

LCR>Получается, что dirty нужно расширять так, чтобы он стал полноправным типом, и систему типов так, чтобы обеспечить комфорт с манимуляцией такими типами. Ты уже понял, куда мы пришли?


Этлучается у тех кому абстракные рассуждения давно затмили разум.
Практика же давно доказала, что все это не более чем пустопорожний тереп.
Я не всегда согласен с Гапертоном (мягко говоря), но тут я целиком и полностью не его стороне.
Тот же Intel C++ давно доказал, что параллелить можно даже до мозга костей импереативый С++. Совершенно плевые подсказки компилятору позволяют сделать программу параллельной и получать реальный выигрышь от наличия несколькоих процессоров. Компьюет же еще очень долго не смоежет распараллеиливать вычисления сам, так как он не всилах предугадать, какие участки имеет смысл параллелить, а какие нет. Фактически для таких вещей нужен искуственный интелект. Ну, или по крайней мере очень сложные системы которые просто не позубам любителям.
Так что введение в язык простых декларативных средств позволяющих подксказать компилятору что и как надо параллелить на мой взгляд лучшее решение на сегодня. И пометки кода "как чистого" вполне достаточно для облегчения жизни компилятора.

LCR>Единственное, что напрягает — это императивный код в Хаскелле выглядит совсем не так, как скажем в Йаве. И это реально беспокоит новичков. Надо было или насахарить побольше, или что-то другое. Но уже в общем-то не нужно.


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

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

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

G>>Угу, а что остается? Назовите полезные, не академические задачи, где Хаскель рвет всех. А то на пустом множестве, сами понимаете, доказать можно все что угодно — на нем верно все.

LCR>Не надо крайностей.

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

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

LCR> Так получилось, что killer-app пока нет.


Да не нужно какого-то "killer-app" просто покажите этот супер-выигрыш на практике. И не в дурных никому не нужных примерах из области показной математики, а что-то более практичное.
А если таких примеров нет, то давайте признаем, что Хаскель позволят писать приблизительно так же как и на других ФЯ.

LCR> Однако, Хаскелл применяется в целой куче областей и небезуспешно.


И что это доказывает? Ассемблер наверно тоже где-то применяется и точно не без успешно.

LCR> Думаю что с помощью чистого нестрогого языка будет возможно строить сверхбольшие системы — это может быть killer-app. Может быть это будет Хаскелл, может Clean, а может быть и Хаскелл-2


Большие системы уже много лет создают на С++, Яве и C#-е, то есть на в доску императивных ООЯ. Ведь главное для больших систем это возможность выделения абстракций и модульность. Так что это вообще не разговор. Монады Хаскеля вряд ли что-то тут решат.

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

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

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

LCR>А _доказать_ здесь всё равно невозможно ничего, сам понимаешь. Так что в определённый момент нам нужно будет просто остановить наше бодание.


Дык доказывать тут просто невозможно. Оба подхода — это дизайнерские решения. Оба они будут работать. Так что пытаться доказать, что "пометка кода как чистого или ленивого — это глпость" — это само по себе глупо. Так же как глупо доказывать обртное. Но вот необходимости выбора это не устраняет. Мне кажется "чистые" решения Хаскеля не приспособлены для реальной жизни. Возможно когд-нибудь все поменяется. Но жить нужно сейчас. И выбор нужно делать сейчас.
Ведь по сей день львиная доля софта пишется на языках дизайн которых устарлен еще 10 лет тому назад.
Почитай "Дизайн и эволющию С++". Это же рассказ о том как принимались плохие решения и чем они были обоснованы. И ведь все эти плохие решения в итоге создали ЯП который доминирует в мире последние 13 лет! Если бы в С++ в те времена было принято хотя бы одно решение в стиле монад, то язык с треском бы провалился. Сегодня не те веремена, но подобные решения все равно практически не приемлемы. Принимая их ты обрекаешь свой язык быть вечным эксперементом.


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


G>>Какие конкретно техники и грабли он не должен за собой тащить?


LCR>многословность,

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

Ага, точно! И если нам вдруг в библиотеке нужно создать эффективную сортировку массива, то мы обосремся, но не позволим тупо написать QuickSort в императивном сител. Отличное решение! Очень в духе пуританства.

G>>А для Хаскеля у нас автоматических распараллеливателей дофига, да? Кстати, фортрановские и сишные программы уже давно параллелят автоматически — это например интеловские компиляторы умеют.


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


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

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


LCR>Хм. А чем обусловлена такая "невытаскиваемость в принципе"?


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

LCR> Или ты априори предполагаешь, что переллелизатор не может быть оформлен в виде библиотеки? Или передать туда информацию кроме как исходный код в принципе невозможно?

LCR>На всякий случай, может быть ты не видел:
LCR>Параллельный OCaml
Автор: Mirrorer
Дата: 06.02.07
. Вот это шаг в светлое будущее.


Читаем первый же коментарий к этому сообщению:

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


К тому же заметь. ОКамл это не ленивый, не чистый ЯП. Так что ты привел замечательный пример того что чистота и ленивость по умолчанию не являются обязательными для эффективного распараллеливания.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 25.02.07 16:32
Оценка:
Здравствуйте, VladD2, Вы писали:

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


Вполне возможно. Скорее всего, в большинстве случаев именно так. Только ты за своей категоричностью совершенно забываешь, что "реальные жизни" они разные даже у одного человека.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[17]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.02.07 17:00
Оценка:
Здравствуйте, lomeo, Вы писали:

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


Я выражаю свое мнение, и рассуждаю о массовм применении. В чем тут катигоричность? И почему ты не считашь обратное мнение катигоричным ни смотря на то, что вся практика показвает, что люди не принимают языки вроде Хаскеля в серьез?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 26.02.07 08:32
Оценка: 66 (6) +1
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

G>>О поддержании чистоты может позаботится компилятор и в грязном языке, если вы введете модификатор pure (или наоборот — dirty) для функций. В этом случае компилятор проверит и докажет чистоту.


G>>Монадный ввод-вывод не сильно будет отличаться по сути — монады точно так же "заражают" код, и выглядит он все равно императивно. В любом случае будет разумно отделить одно от другого, нет? Так в чем реальная разница?


LCR>Таак, ты (можно на "ты"?) наступил на ту же самую граблю, искры от удара которой я имел возможность лицезреть здесь
Автор: Last Cjow Rhrr
Дата: 08.02.07
. Если немного подумать, то окажется, что


LCR>1. грязь бывает очень разная — то есть грязь имеет тип.

?! В самом деле, сэр? ("И прекратите говорить мне "в самом деле", Дживс. Каждый раз мне слышится вместо этого, "обалдели, сэр?"" — из рассказов про Дживса) Пример, плз.

LCR>2. часто хочется выполнить грязный код внутри чистого — а это значит, что все проверки компилятора накрываются медным тазом.

Разумеется, нет. Это всего-навсего означает, что компилятор даст тебе по рукам, если ты весь код не пометишь как грязный. Попробуй в Хаскеле вставить логгирование куда-нибудь вниз гражданского кода — огребешь тоже самое в точности. Или будешь вынужден протащить параметр наверх, или расставишь везде свой монадный dirty. Нет?

LCR>3. монадические значения — это обычные значения. Их можно сохранять в коллекциях, частично выполнять, передавать в ФВП, (де)сериализовывать и прочее. Их нужно только выполнять в нужном контексте и об этом следит система типов. Что может предложить 'dirty' в качестве ответа?


Ужос. Dirty (и строгий язык) может предложить в качестве ответа простой и интуитивно понятный интерфейс с внешним миром — COM и CORBA интерфейсами, файлами, сокетами, библиотеками, а также нормальные эксцепшены, которых в хаскеле нету, и приходится протаскивать ошибку наверх. И не надо мне говорить, что их можно через монады сделать .

LCR>4. если идти дальше, то модификатор dirty должны иметь не только функции, но типы параметров в таких функциях как map. То есть

LCR>
LCR>map      :: dirty(a -> b) -> [a] -> [b ]
LCR>map_pure :: (a -> b) -> [a] -> [b ]
LCR>

LCR>должны рассматриваться как разные функции и тогда каждую функцию нужно реализовывать в 2х экземплярах, а это не может не напрягать.

Ты абсолютно прав. Можно, кстати, шибко далеко не идти, и сразу заглянуть, как это сделано в... С++. Делаем dirty частью сигнатуры (как const), разрешаем описывать generic-функции без указания модификатора.

LCR>Либо надо обеспечить преобразование чистой функции в грязную ( изобрели лифтинг). Теперь предположим мы проектируем какой-нибудь общий интерфейс — нам придётся повсюду воткнуть туда dirty, мы же не хотим проблем в будущем... И где теперь поддержка компилятора?


Разумеется, нет. Процесс проектирования в грязном языке несколько другой, не так все плоско. На крупном уровне декомпозиции делают "грязные" классы — это удобно. Логика которых внутри описываются чисто. Пример языка, где сделано так — Эрланг. Таким же образом разумно проектировать и в OCaml c Nemerle. Я как-то об этом уже писал.

LCR>5. и как избежать транзитивного замыкания грязи, когда у нас 99.9% функций становятся грязными лишь потому, что мы где-то в глубине немножечко замарались?

Вспомни mutable. Очень, очень хорошо помогает, например, для генераторов случайных чисел, которые по сути чистые, а технически — грязные.
А вообще — проблема решается не так. См выше.

LCR>Получается, что dirty нужно расширять так, чтобы он стал полноправным типом, и систему типов так, чтобы обеспечить комфорт с манимуляцией такими типами. Ты уже понял, куда мы пришли?


Не типом, а модификатором типа. Да, система типов усложнится. Если у тебя строгая статическая типизация, конечно .

G>>Угу, а что остается? Назовите полезные, не академические задачи, где Хаскель рвет всех. А то на пустом множестве, сами понимаете, доказать можно все что угодно — на нем верно все.

LCR>Не надо крайностей. Так получилось, что killer-app пока нет. Однако, Хаскелл применяется в целой куче областей и небезуспешно. Думаю что с помощью чистого нестрогого языка будет возможно строить сверхбольшие системы — это может быть killer-app. Может быть это будет Хаскелл, может Clean, а может быть и Хаскелл-2

Сверхбольшие? Вот это — сильно вряд-ли. Практика применения Хаскела у нас показывает, что у него все очень херово с maintainability — практически как у злого С++. Если code standard не ввести — то в программе уже среднего размера черт ногу сломит. Что будет на больших системах — подумать страшно. Это раз.

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

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

LCR>А _доказать_ здесь всё равно невозможно ничего, сам понимаешь. Так что в определённый момент нам нужно будет просто остановить наше бодание.


Можно обосновать.

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

LCR>Возможность чего-то там рассчитать как раз имеет дело с вычислительной простотой. Семантическая простота — это "копать от забора до обеда, а выбор траектории и формы лопат меня не волнует".

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

LCR>Трудности с расчётами возникают очевидно из-за того, что если у нас f имеет сложность O(N), g имеет сложность O(N^2), то композиция (f . g) совсем необязательно будет иметь сложность O(N^3) как в энергичном языке, а может быть всё, что угодно — от O(N^3) до O(1) — зависит от условий на входные данные. И это я считаю очень интересной особенностью нестрогих языков.


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

LCR>В конце концов,

LCR>

LCR>The physical causality works as follows. The brain issues the orders which propagate sequentially through the nerves, make the articulations and the limbs move, and finally the end effector — the hand — grasps the kettle and put in on the fire. Anybody protests?

LCR>Время реакции на раздражитель тоже недетерминировано и ничего — живём и даже радуемся. Возвращаясь к расчётам: часто на практике статистических данных достаточно. А отсутствие гарантий — это нормально в том числе и для энергичных языков и достаточно больших систем.

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

Что будет происходить на практике — сие науке не известно, за отсутствием широкой практики. Результаты нашего evaluation Хаскеля показывают следующее:
1) Хаскель — довольно быстрый язык.
2) Чужой код на хаскеле очень трудно понимать — требуется жестко ограничить выразительные средства и стиль кодирования code standard-ом.
3) Отладчика нет, и это плохо.
4) Просто никакая обработка ошибок — реальную систему с логгированием и "промышленными" реакциями на ошибки хрен напишешь — вот это реально showstopper.
5) Интероп делается через задний проход. Это тоже почти приговор.
6) Ленивость надо давить, проставляя строгость руками. Иначе будет плохо очень. Например — ленивость может давать мемори лики (накапливается где-то невычисленая цепочка по редкой ветке, отжирая память). Это отдельный этап отладки, отсутствующий в нормальных языках.
7) Отдельные вопросы вызывает тестирование ленивых программ — это что ж такое надо сделать, чтобы обеспечить 100%-е тестовое покрытие, а? А мерять его как? Здесь, может, и все ок, но что-то не верится.

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


G>>Какие конкретно техники и грабли он не должен за собой тащить?


LCR>многословность,

LCR>отсутствие проверяемого разделения чистого и грязного кода,
это даже в С++ есть. const + mutable
LCR>слабый клей
Это не предполагает чистоты, не так ли?

G>>А для Хаскеля у нас автоматических распараллеливателей дофига, да? Кстати, фортрановские и сишные программы уже давно параллелят автоматически — это например интеловские компиляторы умеют.

LCR>Ещё раз — я не утверждаю, что Хаскелл — рулез форева. Давай не будем скатываться в пинание конкретного языка, а то и компилятора.
Ну, а тогда о чем мы, собственно? Читату из "мгновений" я уже приводил

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


LCR>Хм. А чем обусловлена такая "невытаскиваемость в принципе"? Или ты априори предполагаешь, что переллелизатор не может быть оформлен в виде библиотеки? Или передать туда информацию кроме как исходный код в принципе невозможно?


Информацию о параллелизме ты вытащишь, это не фокус. Ты не вытащишь информацию о локальности вычислений в программе и о потоках данных — она в статике не получается. Из-за этого и происходит просадка в производительности при увеличении узлов — причина в плохом управлении локальностью вычислений.
Re[5]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 26.02.07 10:46
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>2. часто хочется выполнить грязный код внутри чистого


А зачем это делать?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 26.02.07 10:54
Оценка:
AndreiF,

LCR>>2. часто хочется выполнить грязный код внутри чистого


AF>А зачем это делать?


Матрички умножить или в лог вывести.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[6]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 12:06
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Ужос. Dirty (и строгий язык) может предложить в качестве ответа простой и интуитивно понятный интерфейс с внешним миром — COM и CORBA интерфейсами, файлами, сокетами, библиотеками, а также нормальные эксцепшены, которых в хаскеле нету, и приходится протаскивать ошибку наверх. И не надо мне говорить, что их можно через монады сделать .


Вы не моглы бы уточнить в 2 словах, что такое "нормальные эксцепшены" и "протаскивать ошибку наверх"?

G>Ты абсолютно прав. Можно, кстати, шибко далеко не идти, и сразу заглянуть, как это сделано в... С++. Делаем dirty частью сигнатуры (как const), разрешаем описывать generic-функции без указания модификатора.


А зачем этот детский лепет??? Что не так с IO???
В монадах нет совершенно никакой мистики. С точки зрения ЯЗЫКА они ВООБЩЕ НИКАК не отличаются от любых других классов типов, кроме 2 вещей:
1. Специального do-синтаксиса. То, что он есть, ОЧЕНЬ хорошо и важно, но он не является необходимым
2. Наличия выделенной монады IO для "внешнего мира"
Система типов Хаскелла + монада IO просто тривиально мощнее чем эти *НЕ ПОНЯТНО ЗАЧЕМ НУЖНЫЕ* предложения.
FFI Хаскелла вообще великолепен — считается одним из лучших (если не лучшим) для языков такого высокого уровня. Какие проблемы, например, с COM? Я, например, легко сделал свою библиотеку для работы с COM таким образом, что там все работает абсолютно прозрачно, то есть буквально как в VB — все нужные преобразования делаются в compile-time.

LCR>>5. и как избежать транзитивного замыкания грязи, когда у нас 99.9% функций становятся грязными лишь потому, что мы где-то в глубине немножечко замарались?

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

*ЛЮБЫЕ* "по сути чистые, а технически — грязные" вещи в Хаскелле можно с помощью unsafePerformIO. Зачем что-то выдумывать?

Проблем с чистотой/грязью в сегодняшнем Хаскелле просто НЕТ.

G>У хаскеля все не очень гут со взаимодействием с внешним миром

У хаскеля все распрекрасно со взаимодействием с внешним миром.

G>Что будет происходить на практике — сие науке не известно, за отсутствием широкой практики. Результаты нашего evaluation Хаскеля показывают следующее:

G>1) Хаскель — довольно быстрый язык.
G>2) Чужой код на хаскеле очень трудно понимать — требуется жестко ограничить выразительные средства и стиль кодирования code standard-ом.
G>3) Отладчика нет, и это плохо.
G>4) Просто никакая обработка ошибок — реальную систему с логгированием и "промышленными" реакциями на ошибки хрен напишешь — вот это реально showstopper.
G>5) Интероп делается через задний проход. Это тоже почти приговор.
G>6) Ленивость надо давить, проставляя строгость руками. Иначе будет плохо очень. Например — ленивость может давать мемори лики (накапливается где-то невычисленая цепочка по редкой ветке, отжирая память). Это отдельный этап отладки, отсутствующий в нормальных языках.
G>7) Отдельные вопросы вызывает тестирование ленивых программ — это что ж такое надо сделать, чтобы обеспечить 100%-е тестовое покрытие, а? А мерять его как? Здесь, может, и все ок, но что-то не верится.

В принципе, не вызывает возражений кроме:
4. так и не понял в чем проблема
5. уже писал про FFI, среди высокоуровневых языков считается фактически лучшим, какого рожна еще нужно?
3. отладчик будет (уже есть в CVS HEAD)

Но пусть оно даже так, ВЫВОДЫ-то каковы? Вы чего хотели на Хаскелле сделать? Вместо чего его использовать?
Re[7]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 26.02.07 13:30
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Матрички умножить или в лог вывести.


Умножение матриц — это разве грязная операция? На вход подаем два значения, на выходе получаем третье, значение функции зависит только от аргументов, при каждом вызове результат один и тот же.
А вывод в лог — он хотя и создает побочные эффекты, но по своей сути это чистая операция, т.к. его побочные эффекты не оказывают влияния на результат работы программы. Если подходить к задаче практически, то проще всего считать вывод в лог "чистой" функцией.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 26.02.07 13:44
Оценка:
AndreiF,

LCR>>Матрички умножить или в лог вывести.


AF>Умножение матриц — это разве грязная операция? На вход подаем два значения, на выходе получаем третье, значение функции зависит только от аргументов, при каждом вызове результат один и тот же.


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

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


Тоже верно. Поэтому я и говорю, что хотя формально функция становится "грязной" — фактически она вполне чистенькая, и её можно безопасно использовать внутри других чистых функций.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[7]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 26.02.07 14:04
Оценка: +1
Здравствуйте, Аноним, Вы писали:

G>>Что будет происходить на практике — сие науке не известно, за отсутствием широкой практики. Результаты нашего evaluation Хаскеля показывают следующее:

G>>1) Хаскель — довольно быстрый язык.
G>>2) Чужой код на хаскеле очень трудно понимать — требуется жестко ограничить выразительные средства и стиль кодирования code standard-ом.
G>>3) Отладчика нет, и это плохо.
G>>4) Просто никакая обработка ошибок — реальную систему с логгированием и "промышленными" реакциями на ошибки хрен напишешь — вот это реально showstopper.
G>>5) Интероп делается через задний проход. Это тоже почти приговор.
G>>6) Ленивость надо давить, проставляя строгость руками. Иначе будет плохо очень. Например — ленивость может давать мемори лики (накапливается где-то невычисленая цепочка по редкой ветке, отжирая память). Это отдельный этап отладки, отсутствующий в нормальных языках.
G>>7) Отдельные вопросы вызывает тестирование ленивых программ — это что ж такое надо сделать, чтобы обеспечить 100%-е тестовое покрытие, а? А мерять его как? Здесь, может, и все ок, но что-то не верится.

А>В принципе, не вызывает возражений кроме:

А>4. так и не понял в чем проблема
А>5. уже писал про FFI, среди высокоуровневых языков считается фактически лучшим, какого рожна еще нужно?
А>3. отладчик будет (уже есть в CVS HEAD)

А>Но пусть оно даже так, ВЫВОДЫ-то каковы? Вы чего хотели на Хаскелле сделать? Вместо чего его использовать?


Мы обсуждали ленивость/строгость по умолчанию. Мои выводы — язык должен быть строгим по умолчанию, с честными побочными эффектами и вводом-выводом без монад.
Re[6]: Ленивость или Энергичность по умолчанию?
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 26.02.07 15:13
Оценка:
Gaperton,

G>>>О поддержании чистоты может позаботится компилятор и в грязном языке, если вы введете модификатор pure (или наоборот — dirty) для функций. В этом случае компилятор проверит и докажет чистоту.


LCR>>1. грязь бывает очень разная — то есть грязь имеет тип.

G>?! В самом деле, сэр? ("И прекратите говорить мне "в самом деле", Дживс. Каждый раз мне слышится вместо этого, "обалдели, сэр?"" — из рассказов про Дживса) Пример, плз.
Да, сэр, абсолютно серьёзно! Если гадим в stdio — это один тип, гхм... извините, грязи, если используем императивный доступ к массивам — это другой, используем FFI — это третий, рисуем окошечки — это четвёртый. Можно даже дальше пойти, и захотеть чтобы операции над разными файлами тоже разруливались компилятором, если этого очень хочется. Вот, вкратце такие примеры-с.

G>Попробуй в Хаскеле вставить логгирование куда-нибудь вниз гражданского кода — огребешь тоже самое в точности. Или будешь вынужден протащить параметр наверх, или расставишь везде свой монадный dirty. Нет?

И да, и нет. Есть ещё liftM и monad transformers, которые сделают преобразования обычных или монадических функций в монадические. Также есть unsafePerformIO, но это уже когда одолевает бессилие

G>Можно, кстати, шибко далеко не идти, и сразу заглянуть, как это сделано в... С++. Делаем dirty частью сигнатуры (как const), разрешаем описывать generic-функции без указания модификатора.

Способ, которым это сделано в C++ вызывает лёгкое головокружение. И всё-таки. Не мог бы ты, глубокоуважаемый Джин, ответить мне на маненький вопрос:
-- Функция map - она чистая или грязная?
map :: (a -> b) -> [ a ] -> [ b ]

Возможно у тебя есть небанальный ответ, а вот мой ответ мне же самому прост как дверь — зависит от типа функции переданной в качестве параметра. Значит "грязнота" должна разруливаться на уровне типов. Развивая мысль далее в этом духе, я прихожу к мысли, что твой dirty будет или синонимом звёздочки в Clean, или монадой в Haskell, или он вообще не будет проверяться в compile-time, как в Эрланге, Окамле, Скале и прочих заслуживающих внимание языках, потому что их системы типов не рассчитаны на такую проверку (т.е. недостаточно мощны). Я не прав?

G>Процесс проектирования в грязном языке несколько другой, не так все плоско. На крупном уровне декомпозиции делают "грязные" классы — это удобно. Логика которых внутри описываются чисто. Пример языка, где сделано так — Эрланг. Таким же образом разумно проектировать и в OCaml c Nemerle. Я как-то об этом уже писал.


Я совершенно согласен, это хороший подход к. Но коли уж мы хотим проверяемости компилятором, я осмелюсь повторить, что мы столкнёмся с 99% грязных функций, то есть по сути проверять окажется нечего. Коли уж ты упомянул Эрланг, позволь мне процитировать Джо:

Notice that I have chosen a particularly simple definition of “dirty.” At first sight it might appear that it would be better to recursively define a module as being dirty if any function in the module calls a “dangerous” BIF or a dirty function in another module. Unfortunately with such a definition virtually every module in the system would be classified as dirty.

И та же самая фигня с функциями. Ниже он определяет грязную функцию, как

A function will be considered dirty if a single call is made to unclean BIF.

что разумеется некорректно, если мы заботимся о проверке "грязноты" компилятором.

G>Сверхбольшие? ... Результаты нашего evaluation Хаскеля показывают следующее...


Хм, огромное спасибо. Мне очень интересно почитать о чужом негативном опыте. "И пепел твоих поражений станет залогом будущих побед". Не так давно была ссылка на ещё один неудачный опыт
Автор: Курилка
Дата: 28.12.06
применения Haskell, там человек попробовал писать на Хаскелле "как на Йаве", и много жаловался на монады.
Вывод: возлюби монады если хочешь обуздать Хаскелл.

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

Судя по приведённым примерам, а также по критике макросов тут
Автор: Gaperton
Дата: 09.08.06
твой indirection level — это просто удалённая избыточная информация такая, что трактовка оставшегося куска по прежнему остаётся однозначной.
Получается, что любой подъём по абстрактной лесенке от низкоуровневых до высокоуровневых абстракций увеличивает этот самый indirection level, независимо от того, как мы подымаемся — новыми функциями, макросами, монадами или абстрактными типами. Почему тогда монады и комбинаторы стоят так особняком?
(Я обещаю дальше не развивать этот оффтоп, но мне интересно, что ты ответишь).

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

А как насчёт возможности комбинировать функции и компоненты без abstraction penalty?

LCR>>Хм. А чем обусловлена такая "невытаскиваемость в принципе"? Или ты априори предполагаешь, что переллелизатор не может быть оформлен в виде библиотеки? Или передать туда информацию кроме как исходный код в принципе невозможно?

G>Информацию о параллелизме ты вытащишь, это не фокус. Ты не вытащишь информацию о локальности вычислений в программе и о потоках данных — она в статике не получается. Из-за этого и происходит просадка в производительности при увеличении узлов — причина в плохом управлении локальностью вычислений.
Я о том, чтобы не оставлять компилятор бороться в одиночку а помочь ему декларативными директивами типа "все эти функции должны выполняться в контекстах потоков внутри платы, а вот эти — внутри стойки, эти можно внутри кластера"... (впрочем это тоже оффтоп).
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[8]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 15:27
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Мы обсуждали ленивость/строгость по умолчанию. Мои выводы — язык должен быть строгим по умолчанию, с честными побочными эффектами и вводом-выводом без монад.


Так называется тема треда. Вы же ударились в обсуждение чистоты/нечистоты. В основном на эту тему я и высказался.

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

И Вы так даже и не намекнули КАКОЙ (то есть ДЛЯ КАКИХ ЦЕЛЕЙ предназначенный) язык должен быть "строгим по умолчанию, с честными побочными эффектами и вводом-выводом без монад".
Re[9]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 15:42
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

AF>>Умножение матриц — это разве грязная операция? На вход подаем два значения, на выходе получаем третье, значение функции зависит только от аргументов, при каждом вызове результат один и тот же.


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


Зачем ЗДЕСЬ мутирующий доступ? Чего Вы собрались мутировать?
Re[9]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.02.07 17:45
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>И Вы так даже и не намекнули КАКОЙ (то есть ДЛЯ КАКИХ ЦЕЛЕЙ предназначенный) язык должен быть "строгим по умолчанию, с честными побочными эффектами и вводом-выводом без монад".


Вообще-то намекали и не раз. Язык нужен исключительно для целей создания прикладного и системного ПО. То есть не для баловства одиночек, а для разработки средних и больших систем.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 18:02
Оценка:
Здравствуйте, VladD2, Вы писали:

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


Даже когда я разрабывал маленькие системы я НИКАК не мог обойтись каким-то одним языком. Например, типичной ситуацией для меня (в недавнем прошлом) был следующий *МИНИМАЛЬНЫЙ* набор:
1. Haskell
2. C++
3. VBA

При этом каждый был на *СВОЕМ* месте.

Но вы, как я понял, обитаете в какой-то своей вселенной.
Re[7]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 26.02.07 18:23
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>>>1. грязь бывает очень разная — то есть грязь имеет тип.

G>>?! В самом деле, сэр? ("И прекратите говорить мне "в самом деле", Дживс. Каждый раз мне слышится вместо этого, "обалдели, сэр?"" — из рассказов про Дживса) Пример, плз.
LCR>Да, сэр, абсолютно серьёзно! Если гадим в stdio — это один тип, гхм... извините, грязи, если используем императивный доступ к массивам — это другой, используем FFI — это третий, рисуем окошечки — это четвёртый. Можно даже дальше пойти, и захотеть чтобы операции над разными файлами тоже разруливались компилятором, если этого очень хочется. Вот, вкратце такие примеры-с.

Понятно. Грязь, разумеется имеет тип. Для "грязных" типов придуманы объекты, инкапсулирующие в себе состояние. В эрланге то процесс, в OCaml, простите — объект.

G>>Попробуй в Хаскеле вставить логгирование куда-нибудь вниз гражданского кода — огребешь тоже самое в точности. Или будешь вынужден протащить параметр наверх, или расставишь везде свой монадный dirty. Нет?

LCR>И да, и нет. Есть ещё liftM и monad transformers, которые сделают преобразования обычных или монадических функций в монадические. Также есть unsafePerformIO, но это уже когда одолевает бессилие

Ок, ставим вопрос конкретно. У вас система, структурированная как набор бесконечно рекурсивных функций, замкнутая ленивыми списками. Типичный такой подход для моделирования состояния в ленивом языке. Знакомая ситуация? Весь из себя чисто функциональный. Что будем делать, если захотим логгирование вставить в один из блоков? Или случайные числа там поюзать?

G>>Можно, кстати, шибко далеко не идти, и сразу заглянуть, как это сделано в... С++. Делаем dirty частью сигнатуры (как const), разрешаем описывать generic-функции без указания модификатора.

LCR>Способ, которым это сделано в C++ вызывает лёгкое головокружение. И всё-таки. Не мог бы ты, глубокоуважаемый Джин, ответить мне на маненький вопрос:
LCR>
LCR>-- Функция map - она чистая или грязная?
LCR>map :: (a -> b) -> [ a ] -> [ b ]
LCR>

LCR>Возможно у тебя есть небанальный ответ, а вот мой ответ мне же самому прост как дверь — зависит от типа функции переданной в качестве параметра. Значит "грязнота" должна разруливаться на уровне типов.

Безусловно.

LCR>Развивая мысль далее в этом духе, я прихожу к мысли, что твой dirty будет или синонимом звёздочки в Clean, или монадой в Haskell, или он вообще не будет проверяться в compile-time, как в Эрланге, Окамле, Скале и прочих заслуживающих внимание языках, потому что их системы типов не рассчитаны на такую проверку (т.е. недостаточно мощны). Я не прав?


Да, то что-то вроде звездочки в Clean. Хотя, как именно от этого перекорежит Хиндли-Милнера, я не знаю — не думал об этом.

Что касательно Эрланга — там динамическая семантика вызова. Так что можно и не проверять.

G>>Процесс проектирования в грязном языке несколько другой, не так все плоско. На крупном уровне декомпозиции делают "грязные" классы — это удобно. Логика которых внутри описываются чисто. Пример языка, где сделано так — Эрланг. Таким же образом разумно проектировать и в OCaml c Nemerle. Я как-то об этом уже писал.


LCR>Я совершенно согласен, это хороший подход к. Но коли уж мы хотим проверяемости компилятором, я осмелюсь повторить, что мы столкнёмся с 99% грязных функций, то есть по сути проверять окажется нечего. Коли уж ты упомянул Эрланг, позволь мне процитировать Джо:

LCR>

Notice that I have chosen a particularly simple definition of “dirty.” At first sight it might appear that it would be better to recursively define a module as being dirty if any function in the module calls a “dangerous” BIF or a dirty function in another module. Unfortunately with such a definition virtually every module in the system would be classified as dirty.

Джо, объективно, неправ. Модули, работающие со структурами данных, такие как queue, gb_trees, sets, и прочие — чисты как слеза младенца. Обработку данных и имеет смысл держать чистой. Ввод-вывод — нет. Также, хорошая практика отделять чистый код в отдельные модули, изолируя побочные эффекы, что и делается при хорошем дизайне на Erlang. К примеру, бехавиорсы заведены именно для того, чтобы грязь по возможности спрятать во фреймворк. Я бы привел соответствующие цитаты Джо, да лень искать. Знаешь — у Маркса можно найти цитату на любой подходящий случай? Так и у Джо.

G>>Сверхбольшие? ... Результаты нашего evaluation Хаскеля показывают следующее...


LCR>Хм, огромное спасибо. Мне очень интересно почитать о чужом негативном опыте. "И пепел твоих поражений станет залогом будущих побед". Не так давно была ссылка на ещё один неудачный опыт
Автор: Курилка
Дата: 28.12.06
применения Haskell, там человек попробовал писать на Хаскелле "как на Йаве", и много жаловался на монады.


Одна проблема. На хаскеле у нас писал potan, thesz (они немножечко так понимают в Хаскеле, если ты знаешь, о ком я), а также немного — garrrr, и еще три человека. Никто из них не знает явы, представляешь?

Наш опыт, кстати, это работающий симулятор суперскалярного процессора MIPS, и интеллектуальный контроллер памяти. Проекты успешно завершены.

LCR>Вывод: возлюби монады если хочешь обуздать Хаскелл.


Я тебе тоже совет дам, если можно. Ты напиши полезную системку на Хаскеле хотя бы в тыщу строк кода, а потом свои выводы делай, ладно?

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

LCR>Судя по приведённым примерам, а также по критике макросов тут
Автор: Gaperton
Дата: 09.08.06
твой indirection level — это просто удалённая избыточная информация такая, что трактовка оставшегося куска по прежнему остаётся однозначной.


LCR>Получается, что любой подъём по абстрактной лесенке от низкоуровневых до высокоуровневых абстракций увеличивает этот самый indirection level, независимо от того, как мы подымаемся — новыми функциями, макросами, монадами или абстрактными типами. Почему тогда монады и комбинаторы стоят так особняком?

LCR>(Я обещаю дальше не развивать этот оффтоп, но мне интересно, что ты ответишь).

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

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

LCR>А как насчёт возможности комбинировать функции и компоненты без abstraction penalty?

Комбинаторный стиль затрудняет читабельность, и снижает maintainability. Сам же в собственном коде не разберешься через год-два. Что говорить о другом человеке?
Впрочем, приведи пример, показывающий что ты хочешь сказать. Я, как Мюллер про сыщиков — считаю что инженерам пристало говорить существительными и глаголами — т.е. конкретно.

LCR>>>Хм. А чем обусловлена такая "невытаскиваемость в принципе"? Или ты априори предполагаешь, что переллелизатор не может быть оформлен в виде библиотеки? Или передать туда информацию кроме как исходный код в принципе невозможно?

G>>Информацию о параллелизме ты вытащишь, это не фокус. Ты не вытащишь информацию о локальности вычислений в программе и о потоках данных — она в статике не получается. Из-за этого и происходит просадка в производительности при увеличении узлов — причина в плохом управлении локальностью вычислений.
LCR>Я о том, чтобы не оставлять компилятор бороться в одиночку а помочь ему декларативными директивами типа "все эти функции должны выполняться в контекстах потоков внутри платы, а вот эти — внутри стойки, эти можно внутри кластера"... (впрочем это тоже оффтоп).
Так можно. Только это, видишь ли, то самое явное выделение потоков, с которым ты борешься. Плюс ко всему — у тебя все равно возникнет проблема с разделяемыми данными. Всю программу надо будет проектировать с учетом параллельного выполнения — данные тебе компилятор автоматом не побьет.
Re[9]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 26.02.07 18:37
Оценка:
Здравствуйте, Аноним, Вы писали:

G>>Мы обсуждали ленивость/строгость по умолчанию. Мои выводы — язык должен быть строгим по умолчанию, с честными побочными эффектами и вводом-выводом без монад.


А>Так называется тема треда. Вы же ударились в обсуждение чистоты/нечистоты. В основном на эту тему я и высказался.


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

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

А>И Вы так даже и не намекнули КАКОЙ (то есть ДЛЯ КАКИХ ЦЕЛЕЙ предназначенный) язык должен быть "строгим по умолчанию, с честными побочными эффектами и вводом-выводом без монад".

СПЕЦИАЛЬНО ДЛЯ ШИБКО УМНЫХ. КАПИТАЛИЗАЦИЯ ВОСПРИНИМАЕТСЯ КАК КРИК, А Я НЕ ЛЮБЛЮ, КОГДА НА МЕНЯ ОРУТ. ЭТО РАЗ.

Ничего объяснять я вам не не обязан и не хочу — мне это совершенно неинтересно. Можете интерпретировать как хотите. Это два.

Всего доброго. Это три.
Re[10]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 19:23
Оценка:
Здравствуйте, Gaperton, Вы писали:

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


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

G>СПЕЦИАЛЬНО ДЛЯ ШИБКО УМНЫХ. КАПИТАЛИЗАЦИЯ ВОСПРИНИМАЕТСЯ КАК КРИК, А Я НЕ ЛЮБЛЮ, КОГДА НА МЕНЯ ОРУТ. ЭТО РАЗ.

G>Ничего объяснять я вам не не обязан и не хочу — мне это совершенно неинтересно. Можете интерпретировать как хотите. Это два.
G>Всего доброго. Это три.

Хоть двадцать пять. Если Вы — архитектор, Вам полезно об этом задуматься, ну а уж если кадровик какой, то да — ни к чему.
Re[11]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.02.07 19:34
Оценка:
Здравствуйте, <Аноним>, Вы писали:

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


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


А>Даже когда я разрабывал маленькие системы я НИКАК не мог обойтись каким-то одним языком. Например, типичной ситуацией для меня (в недавнем прошлом) был следующий *МИНИМАЛЬНЫЙ* набор:

А>1. Haskell
А>2. C++
А>3. VBA

Это лично твои проблемы. И это не значит, что по другому быть не может. Просто ты выбрал языки которые плохо подходят для некоторых областей применения. С++ слишком низкоуровневый. Разработака на нем медленна и чревата ошибками. Плюс он не поддерживает компонентую модель (без подпорок вроде КОМ-а). За то он позволяет получить высокую скорость кода. Хаскель способствует порождению тормозного кода, плох в отладке и итеропе. VBA вообще ублюдок работающий только внутри некоторых приложений МС Офиса.

Но есть скажем C# или Nemerle. Что бы кто о них не говорил, но они позволяют получать быстрый код, вести разработку быстро и просто, отлично поддерживают компонентую разработку и обладают отменным итеропом. Последний ко всему прочему спокойно посоревнуются с Хаскелем в области выразительности в любых областях.

А>При этом каждый был на *СВОЕМ* месте.


В прошлом веке я тоже использовал тондем C++ и VB для ускорения разработки. VB служил клеем и высокоуровенвым средством разработки GUI, а на С++ писались КОМ-объекты выполняющие сложные задачи. Вот только с появлением дотнета и C#-а такой подход себя изжил, так как использовать один язык значительно проще, а C# позволял с легкостью обходиться без С++ и при этом его было легко использовать так же как VB.

А>Но вы, как я понял, обитаете в какой-то своей вселенной.


Это ты точно подметил. Она называется — реальный мир.
В этом мире лучим признается то решение которое приводит к желаемому результату при минимуме физических/умственных затрат.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.02.07 20:30
Оценка:
Здравствуйте, <Аноним>, Вы писали:

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


А>Это у Вас глюки. С таким же успехом можно утверждать, что энергичность по умолчанию вынуждает быть чистым. Чистым хорошо быть ВСЕГДА. Просто к запаху императивной помойки Вы привыкли и он уже не шибает.


Так, пошла демагогия с элементами оскоблений. Если нечего сказать по теме то можно просто промолчать.

Следующее сообщение пдобоного рода (флуд с наездами) буду безжалостно вырезать. Особенно от лица анонимов.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 20:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это лично твои проблемы. И это не значит, что по другому быть не может. Просто ты выбрал языки которые плохо подходят для некоторых областей применения. С++ слишком низкоуровневый. Разработака на нем медленна и чревата ошибками. Плюс он не поддерживает компонентую модель (без подпорок вроде КОМ-а). За то он позволяет получить высокую скорость кода. Хаскель способствует порождению тормозного кода, плох в отладке и итеропе. VBA вообще ублюдок работающий только внутри некоторых приложений МС Офиса.


Это мне напоминает анекдот про Бернарда Шоу и Айседору Дункан: "а что, если он будет красив как я и умен как Вы ?". Вам не приходило в голову, что C++ я использовал там, где нужна скорость и низкоуровневое взаимодействие, Haskell — нетривиальная логика, а VBA — именно с целью использовать все это из "некоторых приложений МС Офиса"?

VD>Но есть скажем C# или Nemerle. Что бы кто о них не говорил, но они позволяют получать быстрый код, вести разработку быстро и просто, отлично поддерживают компонентую разработку и обладают отменным итеропом. Последний ко всему прочему спокойно посоревнуются с Хаскелем в области выразительности в любых областях.


Если я правильно понял, Вы повсеместно используете Nemerle для создания коммерческих приложений? Если не секрет — в какой области? И что именно Вы делаете на Nemerle?

Для меня это звучит совершенно удивительно. Я помню, как в стародавние времена на разные haskell-related mailing lists начали регулярно ходить какие-то люди, собиравшиеся писать Nemerle. Они задавали массу вопросов. Получая ответы, они писали — "это мы делать не будем, то мы делать не будем" и, в конце концов, пропали. Мне до сих пор не известно *НИ ОДНОГО СКОЛЬКО-НИБУДЬ ПРИМЕЧАТЕЛЬНОГО* приложения на Nemerle. Может, я не знаю, где искать? Укажите, пожалуйста. Я вообще всегда был сторонником развитых метасредств, поэтому априорно не испытываю к Nemerle никакой неприязни. Но я не в состоянии найти *НИ ОДНОГО* нетривиального приложения, на нем написанного. Вы скажете — компилятор? Но здесь речь вовсе не идет о компиляторах, ибо, если б речь шла о них, то никому и в голову бы не пришлось отвергать Haskell, который для писания компиляторов приспособлен идеально.

Так что же?
Re[12]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 20:46
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Так, пошла демагогия с элементами оскоблений. Если нечего сказать по теме то можно просто промолчать.


VD>Следующее сообщение пдобоного рода (флуд с наездами) буду безжалостно вырезать. Особенно от лица анонимов.


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

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

Если ваш рост > 2 метров — вам нечего делать в кабине истребителя, но возможно стоит попробовать себя на баскетбольной площадке. Вы критикуете Haskell, но на вопрос "с какой точки зрения" заявляете, типа, "ничего объяснять не обязан ... немерле... вырезать.. москвошвея..."
Re[13]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.02.07 21:06
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Это мне напоминает анекдот про Бернарда Шоу и Айседору Дункан: "а что, если он будет красив как я и умен как Вы ?". Вам не приходило в голову, что C++ я использовал там, где нужна скорость и низкоуровневое взаимодействие, Haskell — нетривиальная логика, а VBA — именно с целью использовать все это из "некоторых приложений МС Офиса"?


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

А>Если я правильно понял, Вы повсеместно используете Nemerle для создания коммерческих приложений? Если не секрет — в какой области? И что именно Вы делаете на Nemerle?


В данный момент работаем над интеграцией Nemerle и VS 2005
Автор(ы):
. Плюс над самим компилятором.


А>Для меня это звучит совершенно удивительно.


Бывает. Жизнь вообще прекрасна и удивительна.

А> Я помню, как в стародавние времена на разные haskell-related mailing lists начали регулярно ходить какие-то люди, собиравшиеся писать Nemerle. Они задавали массу вопросов.


Это интересная информация. Если будут ссылки, то будет еще интереснее.

А> Получая ответы, они писали — "это мы делать не будем, то мы делать не будем"


Интересно, что конкретно?

А>и, в конце концов, пропали.


Видимо они почерпнули то что им было нужно.

А> Мне до сих пор не известно *НИ ОДНОГО СКОЛЬКО-НИБУДЬ ПРИМЕЧАТЕЛЬНОГО* приложения на Nemerle.


<офтоп>
Зачем же кричать? Тебе еще не говорили, что КРИЧАТЬ НЕКРАСИВО?

Мы же не в древней конфе. Здесь для выражения своих мыслей, и для их подчеркивания есть прличный инструменты форматирования.
</офтоп>

А> Может, я не знаю, где искать?


Я бы начал здесь:
http://nemerle.org/svn/nemerle/trunk
http://nemerle.org/svn/vs-plugin/trunk
Два очень довольно примечательных проекта.

А> Укажите, пожалуйста. Я вообще всегда был сторонником развитых метасредств, поэтому априорно не испытываю к Nemerle никакой неприязни. Но я не в состоянии найти *НИ ОДНОГО* нетривиального приложения, на нем написанного. Вы скажете — компилятор?


А что компилятор столь не простого языка — это тривильно? Ну, тогда тебе не составит написать его на Хаскеле в качестве развлекалова на вечер?

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


Ни чем не идеальнее чем тот же Nrmerle или даже O'Caml. Как минимум Haskell не иделен с точки зрения производительности получаемого решения.

А>Так что же?


Если чесно, то все что угодно. Я честно говоря с трудом найду задачи которые будут решаться на нем плохо. Конечно он не применим для задач где кровь из носу требуется отсуствие рантайма (нужен нэйтив-код). И так же в нем нет некоторых фрэйворков/решений вроде легких программно-изолированных процессов Эрланга/Сингулярити. Но все это уже не недостаток зыка, а отсуствие фрэйворков которые как раз этому языку очень даже по зубам.

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

Я согласен с Гапертоном, что любое повышение уровня косвенности вредит решению. Однако я так же согласен, что иногда без повышения уровня косвенности невозможно решать задачи изящнь и (как это не смешно звучит) просто. При этом разумным решением является заворачивание сложных вещей в обертки срывающие эти сложности. И прдоставлении пользователям конечных решений. Причем все это должно быть прозрачно для пользователей. Они не должны мучиться с выводом данных в лог или использованием императивного алгоритма. Они просто должны получить нужный им инструмент. Вот это я вижу в Немерле и не вижу в Хаскеле.

Ты задашся вопросом какие приложения есть на Немреле? Но почему перед этом ты не задашся вопросом какие приложения есть на Хаскеле?
Немерле можно сказать еще не родился, но на нем уже пишут довольно сложные приложения. И дальше будет тлько больше. Лично мы собираемся переписать на Немерле этот вот сайт. А вот чего добился Хаскель за это время? На мой взгляд он отлично продемнострировал несколько концепций. Причем некоторе из них довольно спорны. Другими словами он является отличныи исследованием, много давшим компьютерной науке. Классы типов лично мне очень понравились. Ленивость по умолчанию тоже весьма интересный эксперемент (но по-моему не продемонстрировавших особых преимуществ). В общем, Хаскель это очень интересно и здорово, но не для реальной жизни.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.02.07 21:29
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Мне, откровенно говоря, было лень заниматься вопросами регистрации,


Это минута от силы.

А> тем более, что я не уверен стоит ли оно того.


Ну, раз принимаешь участие в дисскусси, значит оно тебе надо.

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


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

А>Если ваш рост > 2 метров — вам нечего делать в кабине истребителя, но возможно стоит попробовать себя на баскетбольной площадке. Вы критикуете Haskell, но на вопрос "с какой точки зрения" заявляете, типа, "ничего объяснять не обязан ... немерле... вырезать.. москвошвея..."


Ну, лично я не говорил, что обяснять не обязан. Но я понимаю Гапертона. Он довольно недвусмысленно описал зачем он пробовал применять Хаскель в своей работе. И когда после довльно долгого рассказа
Автор: Gaperton
Дата: 26.02.07
от тебя снова требудт подробностей это выглядит как элемент издевательства.

Самое смешное, что ни он, ни я в общем-то против самого языка ничего не имеем. Мы говорили только о принятом в нем дизайнерских решениях — ленивости по умолчанию и чистоте (точнее способу ее поддержания).

На мой взгяд эти решения делают язык менее приспособленным к жизни. Отсюда и потребность в VB и С++. Если бы Хаскель не имел проблем, то тебе вряд ли потребовались бы другие универсльные ЯП общего назначения коими являются С++ и Васик. И если Васик еще можно использовть хотя бы потому, что он встрен в Опис и запись макросов ведется именно на нем, то потребность в С++ говорит тольк об одном — о наличии недостатков у твоего любимого ЯП. И что-то мне опдсказывает, что недостатки эти в основном проистекают как раз из-за выбора авторами Хаскеля данных дизайнерских решений.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 22:18
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, лично я не говорил, что обяснять не обязан. Но я понимаю Гапертона. Он довольно недвусмысленно описал зачем он пробовал применять Хаскель в своей работе. И когда после довльно долгого рассказа
Автор: Gaperton
Дата: 26.02.07
от тебя снова требудт подробностей это выглядит как элемент издевательства.


Да нет же. Это никак не проясняет где и зачем он пытался применить Хаскелл. Потому и спросил.

VD>На мой взгяд эти решения делают язык менее приспособленным к жизни. Отсюда и потребность в VB и С++. Если бы Хаскель не имел проблем, то тебе вряд ли потребовались бы другие универсльные ЯП общего назначения коими являются С++ и Васик. И если Васик еще можно использовть хотя бы потому, что он встрен в Опис и запись макросов ведется именно на нем, то потребность в С++ говорит только об одном — о наличии недостатков у твоего любимого ЯП. И что-то мне опдсказывает, что недостатки эти в основном проистекают как раз из-за выбора авторами Хаскеля данных дизайнерских решений.


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

Но в любом случае, я должен задействовать кучу разных API. Если они сразу C-compatible — я могу использовать их напрямую, но во всех остальных случаях мне нужно делать переходники. Здесь нет ничего сложного. Например, COM я могу звать и через dispatch, если оно есть, или через vtables — для этого у меня есть кодогенераторы. Это давно отлажено и работает.

Тем не менее, C++ я использовал и буду использовать, поскольку в критических местах это:
1. дает мне предельную производительность;
2. легко интегрируется с основным решением (на Хаскелле).

Почему я использовал VBA — у меня не было фреймворка для отлова событий. Сейчас он есть, и VBA, в принципе, мне не нужен. Без него я уже обхожусь, даже в тех приложениях, что хостятся в MS Office.
Re[15]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.02.07 22:58
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Да нет же. Это никак не проясняет где и зачем он пытался применить Хаскелл. Потому и спросил.


Он же сказал, что создавали систему эмуляции процессора MIPS и интеллектуального контроллера памяти.

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


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

А>Но в любом случае, я должен задействовать кучу разных API. Если они сразу C-compatible — я могу использовать их напрямую, но во всех остальных случаях мне нужно делать переходники. Здесь нет ничего сложного. Например, COM я могу звать и через dispatch, если оно есть, или через vtables — для этого у меня есть кодогенераторы. Это давно отлажено и работает.


Но это опять же сложности. Хотя это уже неудобствно реализации интеропа. Что немного дургая тема.

А>Тем не менее, C++ я использовал и буду использовать, поскольку в критических местах это:

А>1. дает мне предельную производительность;
А>2. легко интегрируется с основным решением (на Хаскелле).

Это и есть доказательство проблем Хаскеля вызванных как раз тем о чем мы говорим.
Лично мне не нужен С++ вот уже 6 лет. Я добиваюсь такой же производительности без него.

А>Почему я использовал VBA — у меня не было фреймворка для отлова событий. Сейчас он есть, и VBA, в принципе, мне не нужен. Без него я уже обхожусь, даже в тех приложениях, что хостятся в MS Office.


Значит эта проблема была вызвана отсуствием фрэйворка/библотеки и по сути не была принципиальной. В случае С++ все совсем не так. Тут проблема принципиальная. И тут Хаскель всегда будет нуждаться в подпорках.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 26.02.07 23:44
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Он же сказал, что создавали систему эмуляции процессора MIPS и интеллектуального контроллера памяти.

Это я видел. Он там упоминал potan'a, Зефирова и еще неизвестно кого. Но никаких указаний, что там Хаскелл повредил — не было. Более того, была фраза, что проект успешно завершился.

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

VD>Но это опять же сложности. Хотя это уже неудобствно реализации интеропа. Что немного дургая тема.
VD>Это и есть доказательство проблем Хаскеля вызванных как раз тем о чем мы говорим.
VD>Лично мне не нужен С++ вот уже 6 лет. Я добиваюсь такой же производительности без него.
VD>Значит эта проблема была вызвана отсуствием фрэйворка/библотеки и по сути не была принципиальной. В случае С++ все совсем не так. Тут проблема принципиальная. И тут Хаскель всегда будет нуждаться в подпорках.

Дело не в legacy. Попробуй перевернуть логику. Можно было бы делать все только на C/C++. Отчего нет? Все вполне заслуженно. Десятки миллионов строк кода. 90% того, что у тебя на столе, написано на C/C++ — это железобетонная реальность. Уж всяко не чета любым Жаба/Nemerle/whatever.

И здесь оказывается, что:
1. Хаскелл рулит;
2. Хаскелл прекрасно интегрируется со всем этим.

Что не так???

Тут все ругают интероп. Кто-нибудь может внятно сформулировать — что не нравится ??? Я этот вопрос уже во всех (sub)ветках задаю — нет ответа.
Re[9]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 27.02.07 03:17
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

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


Значит, надо просто иметь возможность помечать функцию как "чистую". И не будет никакого расползания грязи.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Ленивость или Энергичность по умолчанию?
От: Cyberax Марс  
Дата: 27.02.07 06:29
Оценка:
AndreiF wrote:
> Значит, надо просто иметь возможность помечать функцию как "чистую". И
> не будет никакого расползания грязи.
Gaperton уже предложил спереть "const" из C++
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[11]: Ленивость или Энергичность по умолчанию?
От: Трурль  
Дата: 27.02.07 06:43
Оценка: :))
Здравствуйте, Аноним, Вы писали:

А>Но вы, как я понял, обитаете в какой-то своей вселенной.


Есть такой мир. Там каждый уважающий себя маг должен знать Истинный Язык. А великого знатока ИЯ звали Неммерль.
Re[11]: Ленивость или Энергичность по умолчанию?
От: AndreiF  
Дата: 27.02.07 06:45
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Gaperton уже предложил спереть "const" из C++


Правильная мысль
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Ленивость или Энергичность по умолчанию?
От: Курилка Россия http://kirya.narod.ru/
Дата: 27.02.07 07:19
Оценка:
Здравствуйте, Аноним, Вы писали:

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


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


А>Это у Вас глюки. С таким же успехом можно утверждать, что энергичность по умолчанию вынуждает быть чистым. Чистым хорошо быть ВСЕГДА. Просто к запаху императивной помойки Вы привыкли и он уже не шибает.


Цитата из Tackling the Awkward Squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell от Simon Peyton Jones :

The bottom line is that laziness and side effects are, from a practical point of view, incompatible.
If you want to use a lazy language, it pretty much has to be a purely functional language; if you
want to use side effects, you had better use a strict language.

Re[12]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 27.02.07 08:16
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Цитата из Tackling the Awkward Squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell от Simon Peyton Jones :

К>

К>The bottom line is that laziness and side effects are, from a practical point of view, incompatible.
К>If you want to use a lazy language, it pretty much has to be a purely functional language; if you
К>want to use side effects, you had better use a strict language.


Я, грубо говоря, писал то же самое. "better use a strict language" не потому, что устраняет помойку, а потому, что к этой помойке уже привыкли и более-менее знают где что лежит.
Re[13]: Ленивость или Энергичность по умолчанию?
От: Курилка Россия http://kirya.narod.ru/
Дата: 27.02.07 08:51
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Я, грубо говоря, писал то же самое. "better use a strict language" не потому, что устраняет помойку, а потому, что к этой помойке уже привыкли и более-менее знают где что лежит.


Вопрос заключается в том, что ты это называешь (+ грубо) просто "привыкли", а люди говорят, что на реальных примерах применения lazy-подход оказался не очень выгодным. Противоположных примеров пока не озвучено
Re[14]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 27.02.07 09:33
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Здравствуйте, Аноним, Вы писали:


А>>Я, грубо говоря, писал то же самое. "better use a strict language" не потому, что устраняет помойку, а потому, что к этой помойке уже привыкли и более-менее знают где что лежит.


К>Вопрос заключается в том, что ты это называешь (+ грубо) просто "привыкли", а люди говорят, что на реальных примерах применения lazy-подход оказался не очень выгодным. Противоположных примеров пока не озвучено


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

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

Я Вам больше скажу. Вы даже не сможете точно определить ленивость и строгость в impure случае. Потому что для него нет сколько-нибудь внятных теорий. Остаются одни разговоры. Типа, "функция обязательно вычисляет все аргументы", но в impure случае строго не определено, ни что такое "функция" ни что такое "вычисляет".
Re[15]: Ленивость или Энергичность по умолчанию?
От: Курилка Россия http://kirya.narod.ru/
Дата: 27.02.07 09:55
Оценка: +1
Здравствуйте, Аноним, Вы писали:


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


Давай, не будем делать необоснованных заявлений, пожалуйста

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


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


А теперь расскажи, что из этого следует для серьёзных софтовых систем. Чистота ради чистоты — это круто. Но в реальности нужно решать конкретные задачи. Давай исходить из этой предпостылки.
Re[17]: Ленивость или Энергичность по умолчанию?
От: Klapaucius  
Дата: 27.02.07 13:01
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Не понял


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

K>>Представте, что я тормоз и напишите код, который решает ту же самую задачу, выделяя O(1) памяти.

L>hFileSize? Делается точно также как и везде. В цикле читается буфер пока-не-EOF.

Я в экстазе, дорогая редакция! Короче говоря, я должен написать на C функцию и воспользоваться ей через FFI, так чтоли?
А если я хочу представить файл в виде списка, к которому можно будет применять map, fold, etc., но не поднимать его при этом в память полностью?

K>>Тут все дело в том, что используется чаще, lazy или strict.

L>Зависит от задач, имхо.

Я тоже так считаю.

L>Мы вообще о чем говорим? С чем Вы не согласны из того, что я сказал?


Ну вот опять пошло, поехало.

Кто я? Где я? Куда я, куда?!

Из чего вообще следует, что я с чем-то там не согласен. Я не готов с чем-то несоглашаться априори, мне нужна информация. Я просто задал вопрос.
... << RSDN@Home 1.2.0 alpha rev. 655>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[17]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.07 13:11
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Это я видел. Он там упоминал potan'a, Зефирова и еще неизвестно кого. Но никаких указаний, что там Хаскелл повредил — не было. Более того, была фраза, что проект успешно завершился.


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

А>Дело не в legacy.


Ты сам только что утверждал это. Так что как-нибудь определись.

А> Попробуй перевернуть логику. Можно было бы делать все только на C/C++. Отчего нет?


Многие так и делают. Собственно реазультата можно добиться и на ассемблере. Вопрос только в стоимости и времени разработки. У С++ эти показатели самые плохие.

А> Все вполне заслуженно. Десятки миллионов строк кода. 90% того, что у тебя на столе, написано на C/C++ — это железобетонная реальность. Уж всяко не чета любым Жаба/Nemerle/whatever.


Большая часть кода ОС по прежнему написана на С. Но почему-то никто из-за этого не брасается писать что-то именно на этом языке.

А>И здесь оказывается, что:

А>1. Хаскелл рулит;
А>2. Хаскелл прекрасно интегрируется со всем этим.

Где он рулит то? Ты так долго доказывал, что рулит то как раз С++ только потому что на нем много кода написано, а как вывод у тебя вдруг получается, что рулит именно Хаскель.

Ты сам то не видишь алогичности этих рассуждений?

А>Что не так???


У меня вопрос — "Что так?".

А>Тут все ругают интероп. Кто-нибудь может внятно сформулировать — что не нравится ??? Я этот вопрос уже во всех (sub)ветках задаю — нет ответа.


Погляди, например как сделан интероп в дотнете. Думаю, вопросы отпадут сами собой. Да и еще раз повторюсь. Если язык полноценный, то и необходимость в интеропе намного меньше. В качестве примера могу привести Интеграцию Немерла со Студией. Для вычислительных и прикладных задач интероп не нужен вовсе, так как сам язык не медленее С++ и при этом имеется куча библиотек. Но интероп нужен для всзаимодействия со Студией. Она написана на С++ с использованием КОМ-а. Но и тут проблем нет. Интероп прозрачен и прост. Его в обще-то не видно даже. Это всего лишь описания интерфейсов и внешних функций. Никаких тебе генераторов, заморочет и т.п.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 27.02.07 13:36
Оценка:
Здравствуйте, VladD2, Вы писали:

Я же написал
А>> Попробуй перевернуть логику
Re[18]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 27.02.07 14:24
Оценка: 19 (2)
Здравствуйте, Klapaucius, Вы писали:

K>Я, видимо плохо объясняю. Мне нужен список, каждый элемент которого вычисляется при использовании. При первом, втором, и так далее.


Возможно, это то, что я здесь понаписал дальше?

K>Я в экстазе, дорогая редакция! Короче говоря, я должен написать на C функцию и воспользоваться ей через FFI, так чтоли?


Не понял зачем С? Только Хаскель, разумеется, только IO монада, отсюда и императив.

K>А если я хочу представить файл в виде списка, к которому можно будет применять map, fold, etc., но не поднимать его при этом в память полностью?


Если нужен именно список, то unsafeInterleaveIO, как всегда, чтобы неленивое вычисление сделать ленивым:

hGetLines :: Handle -> IO [String]
hGetLines handle =
    unsafeInterleaveIO $
    ifM (hIsEOF handle) (return []) $ do
        x  <- hGetLine handle
        xs <- hGetLines handle
        return (x:xs)


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

ifM :: (Monad m) => m Bool -> m a -> m a -> m a
ifM cond yes no =
    do c <- cond
       if c then yes else no


Т.е. какой нибудь hGetLines handle >>= print . head прочтёт только первую строчку. А hGetLines handle >>= print . length прочтёт все, но память будет жрать O(1).

K>Из чего вообще следует, что я с чем-то там не согласен. Я не готов с чем-то несоглашаться априори, мне нужна информация. Я просто задал вопрос.


Не знаю, мне почудились претензии, но какие именно я не понял :-) Извиняюсь.
Re[17]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 28.02.07 08:50
Оценка: :))
Здравствуйте, Аноним, Вы писали:

А>И здесь оказывается, что:

А>1. Хаскелл рулит;
А>2. Хаскелл прекрасно интегрируется со всем этим.

А>Что не так???


Да есть пара пунктов, так, замечаний по мелочи.
1. Хаскель нифига не рулит ни разу.
2. Хаскель херово интегрируется с внешними системами.

А в остальном ты все правильно сказал.

Re[18]: Ленивость или Энергичность по умолчанию?
От: Аноним  
Дата: 28.02.07 23:05
Оценка: +1
Здравствуйте, Gaperton, Вы писали:

G>Да есть пара пунктов, так, замечаний по мелочи.

G>1. Хаскель нифига не рулит ни разу.
G>2. Хаскель херово интегрируется с внешними системами.

Ну, не рулит, так не рулит — Вам виднее.
Напоследок, соблаговолите уж, назовите какую-нить "внешнюю систему" с которой Хаскелл "херово интегрируется".
Re[19]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.07 09:42
Оценка:
Здравствуйте, <Аноним>, Вы писали:

G>>Да есть пара пунктов, так, замечаний по мелочи.

G>>1. Хаскель нифига не рулит ни разу.
G>>2. Хаскель херово интегрируется с внешними системами.

А>Ну, не рулит, так не рулит — Вам виднее.


Интересно, ты действительно не понял, что он сдебался над уровнем аргументации, приводя инвертированный аналог?

А>Напоследок, соблаговолите уж, назовите какую-нить "внешнюю систему" с которой Хаскелл "херово интегрируется".


Дотент. Интеграция просто нулевая. Даже специально портированный и доработаенный клон практически не пригоден для использования.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Ленивость или Энергичность по умолчанию?
От: GlebZ Россия  
Дата: 02.03.07 11:39
Оценка: +1
Здравствуйте, Gaperton, Вы писали:

G>2) Чужой код на хаскеле очень трудно понимать — требуется жестко ограничить выразительные средства и стиль кодирования code standard-ом.

А вот это мне особенно интересно. Если не секрет, как вы описали стили кодирования? Если тайна, можно примерно на словах описать?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[6]: Ленивость или Энергичность по умолчанию?
От: ironwit Украина  
Дата: 03.03.07 06:55
Оценка:
Здравствуйте, VladD2, Вы писали:

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



BZ>>уверяю тебя, что не меньше 80% кода в твоих задачах вообще не сказывается на конечной проивзодительности продукта.


VD>Уверяю тебя, что лучше тебя знаю где мне требуется производительность, а где нет. Я в этом вопросе уже свору собак съел.

чем ругатся лучше бы сказал задачу которая у тебя идет на пределе современного железа?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Я не умею быть злым, и не хочу быть добрым.
Re[7]: Ленивость или Энергичность по умолчанию?
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.03.07 10:17
Оценка:
Здравствуйте, ironwit, Вы писали:

I>чем ругатся лучше бы сказал задачу которая у тебя идет на пределе современного железа?


У меня еще небыло других задач. Всегда хотя бы один участок кода, да требует максимально доступной производительности. К примеру, сейчас для интеграции Nemerle с VS нужно обеспечить максимально возможную скорость парсинга проекта. Парсинг делает штатный компилятор. Таким образом первый садии компилятор должен длетаь максимально быстро. Конечно 10% разницы никто не заметит. Но если бы использовался интерпретатор, то десятикратное отставание было бы просто неприемлемо.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Ленивость или Энергичность по умолчанию?
От: ironwit Украина  
Дата: 03.03.07 11:06
Оценка:
Здравствуйте, VladD2, Вы писали:

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


I>>чем ругатся лучше бы сказал задачу которая у тебя идет на пределе современного железа?


VD>У меня еще небыло других задач. Всегда хотя бы один участок кода, да требует максимально доступной производительности. К примеру, сейчас для интеграции Nemerle с VS нужно обеспечить максимально возможную скорость парсинга проекта. Парсинг делает штатный компилятор. Таким образом первый садии компилятор должен длетаь максимально быстро. Конечно 10% разницы никто не заметит. Но если бы использовался интерпретатор, то десятикратное отставание было бы просто неприемлемо.


понятно. спасибо.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Я не умею быть злым, и не хочу быть добрым.
Re[7]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 05.03.07 09:05
Оценка: 36 (4)
Здравствуйте, GlebZ, Вы писали:

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


G>>2) Чужой код на хаскеле очень трудно понимать — требуется жестко ограничить выразительные средства и стиль кодирования code standard-ом.

GZ>А вот это мне особенно интересно. Если не секрет, как вы описали стили кодирования? Если тайна, можно примерно на словах описать?

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

Основная проблема со стилями кодирования состояла в том, что Хаскель допускает огромное количество вариантов и подходов к реализации.

В нашем случае — система моделировалась набором бесконечно рекурсивных функций, замкнутых ленивыми списками. Даже это можно сделать двумя способами — что возвращать из функции — кортеж списков или список кортежей? Это первое, что должно быть стандартизовано.

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

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

Что-то вроде того. Да, еще нужно соглашение по поводу того, как делаются вещи типа логгирования — это должно быть сделано единообразно.

Ну и далее — нужно стилевое руководство для простого кодирования, что-то вроде best practices. С ним наибольшие проблемы, так как совершенно непонятно, что будет лучше а что хуже, в силу небольшого количества проессионалов в Хаскеле и небольшого опыта промышленного применения Хаскеля группами людей. В результате, людям сложно между собой договориться — нет общей базы.
Re[6]: Ленивость или Энергичность по умолчанию?
От: thesz Россия http://thesz.livejournal.com
Дата: 07.03.07 14:53
Оценка:
LCR>>2. часто хочется выполнить грязный код внутри чистого — а это значит, что все проверки компилятора накрываются медным тазом.
G>Разумеется, нет. Это всего-навсего означает, что компилятор даст тебе по рукам, если ты весь код не пометишь как грязный. Попробуй в Хаскеле вставить логгирование куда-нибудь вниз гражданского кода — огребешь тоже самое в точности. Или будешь вынужден протащить параметр наверх, или расставишь везде свой монадный dirty. Нет?

Нет.

В Hawk лазить не стал, вот пример из нашего framework:
probesDir = "Probes"

probe'' f fn s = mapS writeProbe $ zipS s $ fromList [0..]
    where
        writeProbe (x,n) = unsafePerformIO $ do
            h <- openFile (probesDir++"/"++fn) (if n == 0 then WriteMode else AppendMode)
            hPutStrLn h $ show n++": "++show (f x)
            hClose h
            return x
probe' f fn s =
    -- choose one:
    --s    -- no probing.
    probe'' f fn s    -- probing.

probe fn s = probe' id fn s


Если поток значений пропустить через probe (
probe showFunction "probename" stream
), то получится такой же поток, только с созданием отчета при вычислениях (то есть, всегда.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[7]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 11.03.07 15:18
Оценка:
Здравствуйте, thesz, Вы писали:

G>>Разумеется, нет. Это всего-навсего означает, что компилятор даст тебе по рукам, если ты весь код не пометишь как грязный. Попробуй в Хаскеле вставить логгирование куда-нибудь вниз гражданского кода — огребешь тоже самое в точности. Или будешь вынужден протащить параметр наверх, или расставишь везде свой монадный dirty. Нет?


T>Нет.


T>В Hawk лазить не стал, вот пример из нашего framework:

хъ
T>Если поток значений пропустить через probe (
probe showFunction "probename" stream
), то получится такой же поток, только с созданием отчета при вычислениях (то есть, всегда.


unsafePerformIO играет роль const_cast в С++. В случае хаскеля это означает "внутри нашей чистой функции есть грязный код — вот он. Но мы закрываем на то глаза. И будь что будет". Это, пнимаешь ли, из той же оперы, что и монадный dirty.

Существенной разницы со строгим языком с побочными эффектами нет, не так ли?

pure f( X ) ->
X = do_something(),
X = make_pure( perform_hardcore_IO( X ) ),
do_something_else( X, Y ).
Re[8]: Ленивость или Энергичность по умолчанию?
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 11.03.07 18:00
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>unsafePerformIO играет роль const_cast в С++. В случае хаскеля это означает "внутри нашей чистой функции есть грязный код — вот он. Но мы закрываем на то глаза. И будь что будет". Это, пнимаешь ли, из той же оперы, что и монадный dirty.


G>Существенной разницы со строгим языком с побочными эффектами нет, не так ли?


С другой стороны, логгирование обычно слабо связано с логикой работы функции/программы. В частности, побочный эффект, который оно вызывает, не влияет на работу функции/программы. Функцию по прежнему можно считать чистой (с точки зрения логики программы). Поэтому для логгирования, по моему, unsafePerformIO вполне допустим.

Хотя я бы всё же предпочёл это явно пометить монадой. Это потому, что в логгировании ленивого исполнения я большого смысла не вижу.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Ленивость или Энергичность по умолчанию?
От: Gaperton http://gaperton.livejournal.com
Дата: 12.03.07 07:58
Оценка: +1
Здравствуйте, lomeo, Вы писали:

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


G>>unsafePerformIO играет роль const_cast в С++. В случае хаскеля это означает "внутри нашей чистой функции есть грязный код — вот он. Но мы закрываем на то глаза. И будь что будет". Это, пнимаешь ли, из той же оперы, что и монадный dirty.


G>>Существенной разницы со строгим языком с побочными эффектами нет, не так ли?


L>С другой стороны, логгирование обычно слабо связано с логикой работы функции/программы. В частности, побочный эффект, который оно вызывает, не влияет на работу функции/программы. Функцию по прежнему можно считать чистой (с точки зрения логики программы). Поэтому для логгирования, по моему, unsafePerformIO вполне допустим.


Разумеется — да. Именно в таких случаях и применяют const_cast в С. Я к тому, что эффективного практического отличия от кода с явными побочными эффектами здесь нет. То же самое, только вид сбоку.

L>Хотя я бы всё же предпочёл это явно пометить монадой. Это потому, что в логгировании ленивого исполнения я большого смысла не вижу.


Смысл такого логгирования есть — при декомпозиции через ленивые списки бесконечно рекурсивные функции описывающие блок у тебя ведут себя как параллельные процессы, и работают независимо. Соответственно, при попытке вставить туда логгирование у тебя нет особого выхода — либо протягивать еще один выход, в который уйдет лог или прочий ввод-вывод (что криво и неудобно), либо вкрячивать туда unsafePerformIO и делать ввод-вывод локально, от чего ровным счетом никакого вреда не будет кроме пользы (проще так и понятнее). В большинстве ситуаций. Т.е. ИМХО в приведенном thesz примере самое простое и правильное — использовать unsafePerformIO. Кстати, паттерн
Re[10]: Ленивость или Энергичность по умолчанию?
От: vdimas Россия  
Дата: 20.03.07 12:42
Оценка: 14 (1)
Здравствуйте, Klapaucius, Вы писали:

для бесконечного списка можно как-то так:
    public class LazyList<T> : IEnumerable<T>
    {
        private IEnumerator<T> _enum;
        private List<T> _buf = new List<T>();

        public LazyList(IEnumerable<T> seq) {
            _enum = seq.GetEnumerator();
        }

        public IEnumerator<T> GetEnumerator() {
            foreach (T item in _buf)
                yield return item;

            while (_enum.MoveNext()) {
                _buf.Add(_enum.Current);
                yield return _enum.Current;
            }
        }

        IEnumerator IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
    }


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