И все-таки: как же быть с ленивостью в боевом коде?

191 views
Skip to first unread message

Eax Melanhovich

unread,
Jul 2, 2015, 4:34:17 AM7/2/15
to haskell...@googlegroups.com
Всем привет.

Извиняюсь за то, что поднимаю утомивший всех вопрос.

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

Сам я этот вопрос пару лет назад внимательно изучал [1] и лучший ответ,
который смог найти - нужно помнить, что язык ленивый, плюс осторожно
тестировать (например, при интеграционном тестировании запускать
приложение в Docker/Vagrant с лимитом по памяти) плюс там где не хочешь
ленивости явно использовать строгие поля в данных и тд. Можно еще
утешить себя тем, что нюансы есть во всех языках. В Си можно выйти за
границу массива, в Scala можно забить трэдпул футурами по одному
запросу пользователя, в Erlang могут переполниться очереди сообщений.

Вопрос заключается в следующем - а не нашел ли кто ответ на этот вопрос
получше? И если у кого-то есть реальные проекты на Haskell (ну мало
ли), как вы в них делаете?

[1] http://eax.me/lazy-evaluation/

--
Best regards,
Eax Melanhovich
http://eax.me/

Alexander V Vershilov

unread,
Jul 2, 2015, 5:05:00 AM7/2/15
to haskell...@googlegroups.com
Здравствуйте

2015-07-02 11:30 GMT+03:00 Eax Melanhovich <ma...@eax.me>:
> Всем привет.
>
> Извиняюсь за то, что поднимаю утомивший всех вопрос.
>
> Есть мнение, что самая большая проблема Haskell, которая отпугивает
> новых адептов, заключается в ленивости языка.

Самая большая проблема Haskell, которая отпугивает новых адептов это,
к сожалению, нежелание учиться. /* Ленивость же, это одна из основных
причин выбора Haskell как языка программирования, в этом мире есть
(N-1) неленивых юзабельных языков, (где N это количество юзабельных языков),
и 0 ленивых (кроме hakell). */

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

Писать понимая, что такое ленивость, как она работает, и что такое
правые и левые
свертки, если что-то неожиданное, то задавать вопросы и читать?
Более подпробно и серьёзно ниже.

> Сам я этот вопрос пару лет назад внимательно изучал [1] и лучший ответ,
> который смог найти - нужно помнить, что язык ленивый, плюс осторожно
> тестировать (например, при интеграционном тестировании запускать
> приложение в Docker/Vagrant с лимитом по памяти) плюс там где не хочешь
> ленивости явно использовать строгие поля в данных и тд.

Для тестирования с лимитом по памяти есть хорошая опция рантайма (-M),
которая уставливает ограничения по памяти

-M<size> Sets the maximum heap size (default unlimited) Egs: -M256k -M1G

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

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

> Можно еще утешить себя тем, что нюансы есть во всех языках. В Си можно выйти за
> границу массива, в Scala можно забить трэдпул футурами по одному
> запросу пользователя, в Erlang могут переполниться очереди сообщений.
>
> Вопрос заключается в следующем - а не нашел ли кто ответ на этот вопрос
> получше? И если у кого-то есть реальные проекты на Haskell (ну мало
> ли), как вы в них делаете?

Только фибоначчи вместо проектов, естественно. В целом у меня достаточно
простые правило (плохо сформулировано, т.к. так и не удалось нормально
обсудить его с теми с тем хотелось):
для data structures использовать строгие поля по умолчанию, если не доказана
необходимость обратного (напр. бесконечные структуры,
структуры поверх которых строятся нексусы (?), затягивание узлов) и ленивые
поля в control structures (т.е. в структурах по которым строится поток
выполнения
программы). Так же брать структуры данных, в которых требуемые свойства
гарантируются построением, напр. если нужнен список строгих структуры, то
логично взять Vector.Unboxed, не путать pinned и unpinned память.


> [1] http://eax.me/lazy-evaluation/
>
> --
> Best regards,
> Eax Melanhovich
> http://eax.me/
>
> --
> Вы получили это сообщение, поскольку подписаны на группу Русский Haskell.
>
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес haskell-russi...@googlegroups.com.
> Чтобы добавлять сообщения в эту группу, отправьте письмо по адресу haskell...@googlegroups.com.
> Просмотреть это обсуждение в Сети можно по адресу https://groups.google.com/d/msgid/haskell-russian/20150702113045.11d88fdc%40fujitsu.
> Настройки подписки и доставки писем: https://groups.google.com/d/optout.



--
Alexander

Maxim Kulkin

unread,
Jul 2, 2015, 4:02:27 PM7/2/15
to haskell...@googlegroups.com
ИМХО, все эти разговоры про ленивость мне кажутся надуманными. Я 1.5 года писал веб-сервис на Haskell и ни разу у меня не было проблем с ленивостью, хотя я на это специально никогда внимания не обращал. Многие библиотеки уже делают для вас все удобно, чтобы не надо было об этом думать. Ну и, да, надо пользовать левые неленивые свертки by default =)

чт, 2 июля 2015 г. в 2:05, Alexander V Vershilov <alexander...@gmail.com>:
Просмотреть это обсуждение в Сети можно по адресу https://groups.google.com/d/msgid/haskell-russian/CAO-1Pb5dUSn73XN3wHQD%2BUNa%2BKom1QFyF3idjXqEgbi9AG0iew%40mail.gmail.com.

Serguey Zefirov

unread,
Jul 3, 2015, 12:27:08 PM7/3/15
to haskell...@googlegroups.com
Внесу свои несколько копеек.

Я не могу согласиться с использованием строгих полей по умолчанию. При их использовании вы лишаетесь возможности чего-то не вычислить лишний раз.

Например, я сожалею о том, что все поля в Data.Map/IntMap строгие (за исключением полей данных), поскольку мне необходимо часто работать со словарями, которые я бы предпочёл не строить вовсе.

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

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

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


2 июля 2015 г., 12:04 пользователь Alexander V Vershilov <alexander...@gmail.com> написал:
Просмотреть это обсуждение в Сети можно по адресу https://groups.google.com/d/msgid/haskell-russian/CAO-1Pb5dUSn73XN3wHQD%2BUNa%2BKom1QFyF3idjXqEgbi9AG0iew%40mail.gmail.com.

Alexander V Vershilov

unread,
Jul 3, 2015, 12:45:40 PM7/3/15
to haskell...@googlegroups.com
Вот по этому я и пытался сформулировать отличие, назвав это control
flow structures
и data structures. Вещи типа отображений и деревьев находятся где-то на границе,
и я бы скорее их отнёс к control-structures, которые скорее должны
быть ленивыми.
Вот использование "конечных" ленивых структур может легко накапливать
вычисления,
например:

foldl' (\(c,d) b -> (c+b,d-b))

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

Но все же не скажу, что мне приходилось часто заниматься выставлением строгости
полям и тратить на это много времени.
> Чтобы отправлять сообщения в эту группу, отправьте письмо на электронный
> адрес haskell...@googlegroups.com.
> Чтобы посмотреть обсуждение на веб-странице, перейдите по ссылке
> https://groups.google.com/d/msgid/haskell-russian/CABFQQ%3DDw%2B-G9opbm2c5nxBXYbsqf%2BpoNTKPbD7cVWx%2B%3DiAYXSw%40mail.gmail.com.
>
> Чтобы настроить другие параметры, перейдите по ссылке
> https://groups.google.com/d/optout.



--
Alexander
Reply all
Reply to author
Forward
0 new messages