| Comments: |
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 10th, 2009 - 06:35 pm |
|---|
| | | (Link) |
|
А что нужно, кстати?
Если практически полезный и популярный, но функциональный язык, то Haskell, скорее всего. Не обязательно же по Душкину.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 10th, 2009 - 07:18 pm |
|---|
| | | (Link) |
|
Скорее интереса (самообразования, раз уж работаю программистом) ради.
А что, в Хаскеле легко подсчитать количество вершин дерева?
В общем, из-за Душкина я плохо понимаю синтаксис, но о возможностях языка он вряд ли врёт.
Мне кажется, что для расширения кругозора лучше всего почитать Филд,Харрисон "Функциональное программирование". В Хаскелле - легко ;). Хаскелл более популярный язык. И в нем больше функциональных наворотов - функции высшего порядка, например. Но и в Рефале есть интересные возможности, которых нет в Хаскелле.
Харрисона и Филда читать точно не надо - там даже элементарные вещи вроде унификации изложены так, что и с поллитрой не разбрешься что это такое, а главно - зачем все это надо.
Мне вот не пришлось изучать основные вещи по этой книге (когда начал читать, про многое уже знал, что это и зачем), но в целом мне она показалась вполне хорошей.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 11:17 am |
|---|
| | | (Link) |
|
Дипломатичное умолчание о том, что же надо читать, не укрепляет желание разобраться-таки с языком:)
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 10th, 2009 - 07:39 pm |
|---|
| | | (Link) |
|
Может и из-за Душкина Хаскел мне уже не понравился.
Распечатаю теперь "классическую книжку Гурина и Романенко" про РЕФАЛ.
Эээ... в книжке слишком формально изложен Рефал+. А основные концепции Рефала (что лучше и нужно сначала изучить) там спрятаны под наворотами Рефала+. Еесли начинать изучать Рефал, то лучше начать с чего-нибудь от сюда.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 12:39 pm |
|---|
| | | (Link) |
|
Спасибо. Вероятно, это наиболее полезный комментарий.
P.S. По поводу Рефала рекомендую посмотреть на реализации Рефал 5 и Рефал+ (или на одну их них - лучше на последнюю ;) ).
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 11:18 am |
|---|
| | | (Link) |
|
Да, я же не диссертацию по истории языка пишу, я и собирался на последнее работающее смотреть.
Ну зависит от того, конечно, как дерево определить. Если так:
data Tree a = E | N (Tree a) a (Tree a)
То число содержащихся в нем значений -
n_leafs E = 0
n_leafs (Tree l _ r) = n_leafs l + 1 + n_leafs r
PS: Но imho Haskell куда проще идет после ML, поскольку идейно он является чем-то вроде ML++ (при довольно сильно перелопаченном синтаксисе, но сохранившем основные понятия)
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 11:47 am |
|---|
| | | (Link) |
|
Да, это я несколько расчувствовался от конструкций Душкина.
На самом деле он тоже несложные деревья ввёл (тоже бинарные, а не просто деревья), да и без пустого дерева.
data Tree a = Leaf a | Branch (Tree a) (Tree a)
Тоже пишется: cnt (Leaf x) = 1 cnt (Branch x y) = cnt x + cnt y
Он же этот вопрос в связи с монадами поднимает.
Думать надо скорее над ситуациями, когда мы хотим подсчитать, например, сумму значений при вершинах дерева с множителями, равными номеру вершины при обходе: при "императивном" обходе с переменной с деструктивным присваиванием это проблемой не является вовсе.
Но и тогда тоже можно написать что-то типа: xxmultisum (Leaf x,(s,i)) = (s+x*i,i+1) xxmultisum (Branch x y,(s,i)) = xxmultisum (y, xxmultisum(x,s,i) ) multisum (Leaf x) = x multisum (Branch x y) = xxmultisum(Branch x y, 0, 1)
Да, проблемы особой нет.
Буду считать, что для моей неокрепшей души Душкин слишком душен.
Монады лучше поначалу вообще не трогать - это самый крышевыносительный элемент языка (и если он поместил его не в конец всего, то он это зря). Хотя монады на этом примере иллюстрировать действительно довольно удобно (другое дело, что они для этого не нужны совершенно).
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 01:24 pm |
|---|
| | | (Link) |
|
Как уже должно было быть ясным из моих комментариев по поводу вериг для Цепепе (чтобы в безумных тестах он стал якобы медленнее), я вообще не понимаю концепции программирования без "побочных эффектов".
Это уже не программа, а одиночное вычисление. Такие программы должны компилироваться в ?вывод? ответа и всё. (Ну, интерпретация — другое дело, но тогда и сравнивать надо не с Цепепе, а с интерактивной работой в Mathematica-е, например.)
Так что без монад мне, как я понял, Хаскел мне совсем неинтересен.
Мне удобно, когда сначала формально дают синтаксис (который я не вполне понимаю) с кратким описанием, а потом на примерах и теорией разъясняют, что к чему. А у Душкина что-то типа "погружения": нет логической последовательности. И такое ощущение, что и у самого Хаскела что-то похожее (с ленивыми вычислениями и рекурсией):)
Дело вкуса конечно, но начинать с монад - примерно тоже самое, что начинать читать учебник по анализу с последней главы (хотя да - монады практически необходимы).
Я про ML упоминал вполне серьезно - ML + Clean + Haskell - действительно очень сильно отличаются от привычных языков (и вовсе не только тем, что "функциональные") - там, например, система типов очень непривычная (а она для понимания критически важна). Шаблоны программирования совсем другие. То есть языки не сильно сложные, но изучение к синтаксису (он, кстати, очень простой) и семантике не сводится даже на половину.
А монады требуют понимания как минимум классов типов (точнее - классов конструкторов типов), и определенного опыта писания того же самого без них (ввод-вывод в Haskell без монад не пишется, а остальное все спокойно - и как раз понимать, что именно инкапсулируется в этот класс очень полезно).
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 02:09 pm |
|---|
| | | (Link) |
|
Ну, сейчас я склонен поизучать РЕФАЛ, а там уж посмотрим.
Но наибольшее, на что рассчитываю — считать какую-нибудь ерунду в качестве хобби. Если бы мне деньги за это платили, то что сказали бы, то и изучал бы (я сейчас программирую на Дельфах, впервые я запустил среду в первый день работы там же, где и сейчас работаю). Забавно, что в этом есть некое невезение: с Дельфами не наблюдается обилия хотя бы отдалённо "шикарных" предложений по работе. И если бы мне надо было программировать на Цепепе (какие-то знания и навыки у меня были и в Паскале, и в Си), то я наверняка уже сменил бы работу:) Правда, я изначально трудоустраивался как специалист по криптографии.
Кстати, как насчёт введения с клавиатуры параметров тестов на случай адекватной оптимизации?
Не думаю, что это сильно изменит результаты ужасного теста с комплексными числами или ?годичной? давности теста с сортировкой, только если в Яве (там, вроде бы, наиболее агрессивная оптимизация, или нет?).
... я вообще не понимаю концепции программирования без "побочных эффектов". Это уже не программа, а одиночное вычисление.
Кроме "побочных эффектов" есть аргументы и результаты. И зачастую этого достаточно. И она многое дает. Например, ленивые вычисления в Haskell'е. Разбираясь с Haskell'ем или Рефалом, я уверен, Вы и в этой концепции разберетесь.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 15th, 2009 - 11:45 am |
|---|
| | | (Link) |
|
Так ввод-вывод же через монады в Хаскеле? А монады неудобные. Я об этом. kouzdra предложил мне считать монады каким-то высшим пилотажем, который надо отложить, а я ответил, что без них я лучше воспользуюсь Mathematica-ой или ещё чем-нибудь таким.
У Haskell'я (по-моему немаленькому опыту использованя) есть два (наверное больше, но смотря на эти примеры вспомнилось два) интересных свойства.
Во-первых, если программа скомпилировалась (Haskell смог проверить и вывести все типы), то она (с очень большой вероятностью) работает правильно. Это некий аналог физического принципа размерностей - если размерность сходится, то формула близка к истине (ну, иногда константу нужно добавить ;)).
И во-вторых, чем программа короче, тем она понятней и лучше. Например, в multisum использовать монады не нужны, т.к. программа станет длиннее. А говоря об этом примере, я бы написал так: tree2List :: Tree a -> [a] -- сравните с исходной cnt ;) tree2List (Leaf x) = [x] tree2List (Branch x y) = (tree2List x)++(tree2List y) Потом все функции реализуются в одну сточку: cnt = sum . tree2List multisum = sum . zipWith (*) [1..] . tree2List
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 15th, 2009 - 12:02 pm |
|---|
| | | (Link) |
|
смог проверить и вывести все типы Теоретические основы и примеры про вывод типов я прочитал. работает правильно Ну это только если с чем-нибудь типа Яваскрипта сравнивать, как мне кажется.
И во-вторых, чем программа короче, тем она понятней и лучше. Ага. Ещё Перл — отличный пример. Зачем же тогда переменные и типы так сложно называть? Можно же в небольшой программе обходиться одним-двумя символами на идентификатор?
Пример с tree2List не очень гибок, по-моему, ибо предполагает определённый порядок обхода, такой же, как у меня в multisum. Для другого порядка придётся переписать что мой multisum, что tree2List здесь.
Меня смущает, что всё это может исполняться неопределённо сложно. Наверное, в результате оптимизаций многого лишнего создаваться не будет, но выглядит это как два прохода по дереву, когда требуется один. В данном случае это не проблема, но больно любят рекурсивность всякую в этом языке, по-моему.
> А что, в Хаскеле легко подсчитать количество вершин дерева?
А какие проблемы?
Кстати, можно посмотреть на SML, он попроще Haskell, хотя многие идеи те же.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 11:49 am |
|---|
| | | (Link) |
|
Кстати, если не нравятся монады и синтаксис языка кажется сложным, то почему бы не посмотреть на более простые и не до конца функциональные языки? Советую SML, как представителя семейства.
Еще есть лиспы, из них по духу более-менее функционален Scheme --- очень простой язык, можно за день изучить; синтаксис сложным точно не покажется.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 07:40 pm |
|---|
| | | (Link) |
|
Сложным особо не кажется, но у Душкина изложен невнятно.
Синтаксис не понравился.
Я не вижу смысла в программировании в первую очередь "без побочных эффектов": для меня сложность монад неоправданна.
Упомянутые свойства перечисленных языков не вызывают интереса.
Функциональная парадигма у меня не вызывает непонимания.
В РЕФАЛе списки двусторонние (в Scheme-Lisp, как я понимаю, тоже односторонние списки), так что на очереди он.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 12:11 pm |
|---|
| | | (Link) |
|
Меня ещё ужасно бесят односторонние списки.
Со списками в основном приходится делать map или fold, или что-то подобное. Списки с возможностью обхода в две стороны требуются очень редко. И если требуются, то недолго написать самому.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 07:29 pm |
|---|
| | | (Link) |
|
Я не понимаю разумности данного ограничения.
требуются очень редко Мне вообще язык этот не требуется. Да и Вы, как я понимаю, не практик.
Неудобства воспринимаю субъективно.
Как-то смущает меня, что вставить элемент в начало или конец — просто, а прочитать — только первый. Сама эта манера писать "x:xs" кажется насилием как "+(a,b)".
Нет, я пишу практический код, но если на функциональных языках, то, таки да, специфический. Так во многих языках. x:xs в Haskell, [H|T] в Prolog, (car . cdr) в лиспах. Я не думаю, что язык должен предоставлять все структуры данных --- он должен позволять их легко реализовать при необходимости. Вот разумные рассуждения, на мой взгляд: http://web.onetel.net.uk/~hibou/Doubly%20Linked%20Lists.html
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 07:51 pm |
|---|
| | | (Link) |
|
Почитаю.
Мне кажется, что язык должен меня ограничивать так, чтобы я не мог, например, написать слишком тормозной программы случайно. Хаскел явно не из таких.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 15th, 2009 - 01:51 pm |
|---|
| | | (Link) |
|
Ну, anti-pattern так anti-pattern.
С точки зрения устоявшегося Лиспа — наверное, разумные.
О нужности двусвязных списков там не написано по сути, аргументы — какие-то смешные проблемы управления в компиляторе/интерпретаторе Лиспа (что-то там у него, видите ли, меняться должно так, а не иначе), как я понял.
![[User Picture]](http://lj.rossia.org/userpic/158330/215) | | From: | do_ |
| Date: | June 10th, 2009 - 09:10 pm |
|---|
| | | (Link) |
|
...евреи обсуждают, что лучше -- haskell или refal. Не стеснялись бы, переходили на иврит.
![[User Picture]](http://lj.rossia.org/userpic/42280/9559) | | From: | ppkk |
| Date: | June 11th, 2009 - 12:31 pm |
|---|
| | | (Link) |
|
РЕФАЛ пишется кириллицей и БОЛЬШИМИ БУКВАМИ! | |