вторник, 29 декабря 2009 г.

[comp.prog.flame] Краткие впечатления от статьи “Элементы функциональных языков”

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

Самое важное – это то, что я, похоже, понял, почему ФП до сих пор не попало в мейнстрим. Ведь, в принципе, в тех самых элементах функционального программирования нет ничего сложного. Многие из них можно объяснять буквально на пальцах. Но!

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

Во-вторых, функциональные языки по своему синтаксису очень и очень сильно в стороне от мейнстримовых C- и Pascal-еподобных языков. А нужно-то всего-ничего:

  • обернуть возможности Haskell/OCaml в привычный большинству C-подобный синтаксис;
  • отказаться от использования однобуквенных имен и имен с черточкой. Вместо:
    curry f = f'
         where f' x y = f (x,y)
    писать по-человечески:
    curry func = carriedFunc
         where carriedFunc x y = func (x,y)
  • таки понять наконец, что скобки и запятые при вызове функций нужны! Поскольку при взгляде на:
    a = f x y * g z w
    должно быть сразу понятно, что это:
    a = f(x, y) * g(z, w)
    а не
    a = f(x, y * g, z, w)
    или
    a = f(x, y) * g(z(w))

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

В общем, пока развитием функциональных языков будут заниматься ученые-математики, ничего в мейнстриме им не светит. Зато, если какой-нибудь программист-практик засунет часть возможностей Haskell-я в C++/C#/D/Java/you-name-it – вот это будет прорыв.

Кстати, поэтому я не очень верю в шансы Scala – ведь его разрабатывают как раз таки академические ученые ;)

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

71 комментарий:

Rustam комментирует...

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

Rustam комментирует...

Насчет a = f x y * g z w все таки достоинства карринга перевешивают небольшие недостатки в виде таких выражений или расстановки скобок при вызовах.

eao197 комментирует...

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

Это в том, название которого начинается с большой буквы N? ;)

>Насчет a = f x y * g z w все таки достоинства карринга перевешивают небольшие недостатки в виде таких выражений или расстановки скобок при вызовах.

А как использование скобок противоречит(мешает) каррингу?

Rustam комментирует...

Это в том, название которого начинается с большой буквы N? ;)

Конечно :)

А как использование скобок противоречит(мешает) каррингу?

В принципе никак, но делает это менее удобным, в том же окамле или хаскеле карринг (с сопутствующими замыканиями) как воздух не заметен и повсюду, в случае скобок уже придется прикладывать специальные усилия. Ну и со скобками free point невозможен.

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

Skynin комментирует...

А мне пока непонятно как на ФП - проектировать. Примеры что приводятся - далеки от насущных задач или - низкого уровня, "для кодера".

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

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

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

Rustam комментирует...

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

Skynin комментирует...

Прямой перевод GOF невозможен
Наверное что так. Но подзадачки такого уровня, для которого предназначены паттерны - останутся.

много функциональных паттернов
Вот мне пока только "низкоорувневые" и встречались. Не искал правда сам, но адепты ФП как-то наводку на них, паттерны уровня GoF - не дали.

Кстати, в тему, недавно нарыл простенькую статью:
Опять про модные монады

Rustam комментирует...

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

eao197 комментирует...

2Rustam:

>В принципе никак, но делает это менее удобным, в том же окамле или хаскеле карринг (с сопутствующими замыканиями) как воздух не заметен и повсюду, в случае скобок уже придется прикладывать специальные усилия. Ну и со скобками free point невозможен.

А пример можно?

jkff комментирует...

> все это осваивается
Это (указанные Вами особенности синтаксиса) осваивается за мизерное время и де-факто описываемых Вами проблем с неоднозначностью интерпретации попросту не существует. Насчет того, что лучше — f' или curriedFunc — это идеологический спор. Мне кажется, что f' намного лучше, и я готов это обсудить, но не в этом комментарии.

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

> Но об этом, с конкретными цитатами, в ближайшие дни.
Жду с нетерпением! Конструктивной критики очень не хватает; как-то больше придираются к верстке или к тому, что "че-то в общем и целом как-то сложновато, лень было вчитываться". Вы не могли бы черкнуть комментарий в соответствующую запись в fprog.livejournal.com , когда опубликуете претензии?

eao197 комментирует...

2jhff:

>Это (указанные Вами особенности синтаксиса) осваивается за мизерное время и де-факто описываемых Вами проблем с неоднозначностью интерпретации попросту не существует.

Возможно, я сильно ошибаюсь, но именно по этой причине ФП все еще находится где-то там. Люди, в большинстве своем, ленивы и ограничены. Поэтому для достижения больших объемов потребления приходится сильно снижать порог вхождения в продукт. В данном случае -- на слом барьера между ML-подобными и C-подобными языками. Вам кажется, что он небольшой. Я с вами не согласен. Но в любом случае барьер есть.

>Мне кажется, что f' намного лучше

А мне нет. Проблема выбора имен в программировании -- чуть ли не самая сложная. И то, что я вижу в примерах программ на функциональных языках сильно противоречит всему моему опыту.

>Жду с нетерпением! Конструктивной критики очень не хватает;

Сразу скажу, что критика будет жесткой, частично субъективной. Так что давайте я ее опубликую и если вы сочтете ее заслуживающей внимания, я дам ссылку в fprog.livejournal.com.

jkff комментирует...

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

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

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

> давайте я ее опубликую
Давайте.

eao197 комментирует...

>В общем, это тема для отдельного обсуждения.

Угу, хорошая тема для отдельной заметки.

Rustam комментирует...

Ну основные преимущества карринга это легкость манипуляции функциями, например все стандартные функции делаются так чтобы менее часто изменяемые параметры стояли левее, что позволяет легко конкретизировать обобщенные функции, например filter ((>) 0) и наоборот каррированные функции легко комбинировать наподобие
let letters = pack % unique % sort % filter is_alpha % unpack % lowercase

eao197 комментирует...

>например filter ((>) 0)

Ну вот за такое бы руки я отрывал бы. Почему бы не писать filter x -> x>0 или filter {|x| x > 0}? Экономия на спичках, имхо.

>let letters = pack % unique % sort % filter is_alpha % unpack % lowercase

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

Rustam комментирует...

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

Чтобы полностью разобраться нужно читать http://alaska-kamtchatka.blogspot.com/2008/01/pointless-polymorphism.html по сути это уже микро или нано DSL но даже не читая суть же понятна по названиям функций, единственно нужно пояснить что pack и unpack чисто служебные для преобразования строки в/из списка.

eao197 комментирует...

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

А почему же сразу крайности? Либо извращение с функторами в STL (и похожие на них локальные классы в Java), либо вершина минимализма в Haskell-е? Должна быть золотая середина.

>но даже не читая суть же понятна по названиям функций

Ага, суть понятна. Детали не видны. Допустим эта конструкция не работает как нужно. Или ты просто делаешь code review чужого фрагмента. Можно ли сразу разобрать, все ли здесь чисто? А то у меня в Ruby бывало так, что запишешь конвейер преобразований, а на выходе окажется, что вместо строки я получаю вектор подстрок, поскольку не ту функцию в середину конвейера влепил.

jkff комментирует...

> вместо строки я получаю вектор подстрок
Это из-за отсутствия статической системы типов. Без нее вообще программирование с функциями высшего порядка едва ли уместно. А вот при ее наличии как раз-таки и начинают наблюдаться эффекты сильного сокращения кода и роста корректности. Попробуйте придумать ошибочный бесточечный «конвейер» на Haskell — it is surprisingly hard :)

eao197 комментирует...

>Попробуйте придумать ошибочный бесточечный «конвейер» на Haskell — it is surprisingly hard :)

Вы сильно недооцениваете границы человеческой глупости и невнимательности :)

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

Rustam комментирует...

Да подобные ошибки что в окамл что в хаскель не пропустит типизация. А подробности конечно в функциях смотришь, а в окамл можно и обычным отладчиком пройтись.

Rustam комментирует...

А чтобы можно было отследить мысль плохого

"Создайте систему, которой сможет пользоваться даже дурак, и только дурак захочет ею пользоваться".

eao197 комментирует...

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

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

>Создайте систему, которой сможет пользоваться даже дурак, и только дурак захочет ею пользоваться

При этом большинство мейнстримовых языков сейчас как раз имеют неплохую защиту от дурака (за исключением, пожалуй, Perl-а). Даже плохой код на C++ поддается расшифровке. Не в последнюю очередь из-за "синтаксического оверхэда".

Rustam комментирует...

По моему это уже логическая ошибка, такие только тестами ловятся (иногда :) ).

На а насчет защиты от дурака на C++ это сюда http://ru.wikipedia.org/wiki/International_Obfuscated_C_Code_Contest :)

eao197 комментирует...

>По моему это уже логическая ошибка

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

>На а насчет защиты от дурака на C++ это сюда

Это не доказательство отсутствия защиты от дурака. Это доказательство отсутствия защиты от больно умных :)

Вот в Eiffel есть защита и от тех, и от других. Наверное, поэтому он мало кому нравится :)

Rustam комментирует...

Да насчет багов согласен, именно мелочь самое страшное :)

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

eao197 комментирует...

>Дурак возьмёт простейший goto и такого наколбасит что на порядок проще будет переписать чем разобраться. По моему это от языка мало зависит.

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

И вот в таких условиях визуально различать ((-)5) и ((-5)) как-то сложновато.

Rustam комментирует...

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

Так такие языки есть та же ява или оберон. Я думаю что ты ошибаешся, такие языки ограничивают нормальных и хороших программистов (для которых в той же яве начинают городить IDE паттерны, кодогенерацию и т. п.) а в результате получим закон Мерфи в действии, кучу "индусов".

И вот в таких условиях визуально различать ((-)5) и ((-5)) как-то сложновато.

А = и == просто? :)

eao197 комментирует...

>Так такие языки есть та же ява или оберон. Я думаю что ты ошибаешся, такие языки ограничивают нормальных и хороших программистов (для которых в той же яве начинают городить IDE паттерны, кодогенерацию и т. п.) а в результате получим закон Мерфи в действии, кучу "индусов".

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

Поэтому мейнстрим должен ориентироваться на большие массы посредственных программистов. Что мы и видим -- Java в мейнстриме, Haskell/OCaml -- нет.

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

>А = и == просто? :)

Я бы предпочел иметь := и ==. Но меня никто не спрашивает :)

Тем более, что эта проблема есть только в C/C++.

Skynin комментирует...

Ваше высокопревосходительство, вы же сами ответ на свой вопрос о высокоуровневых паттернах приводите ссылкой (кстати ссылка не открывается) на монады.
Там - низкоуровневое.
ссылку можно найти запросом к Гуглу - Зубинский монады
видать неправильно как-то оформил ссылку.

О себе: я из крестьянского роду, "дворняга безродная".
Справка: ((Ваше, Его, Их и т. д.) Превосходительство (калька лат. excellentia) — почётный титул и обращение к дворянам или лицам исключительно высокого положения. Титул «Превосходительство» носили до 14 века короли франков, лангобардов и германские императоры. )

...
Почитал обсуждение(26 постов на момент этого), и опять не увидел - а проектировать то как? Все о кодинге да и о кодинге...

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

Skynin комментирует...

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

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

Вот чего пока я не вижу в ФП...

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

eao197 комментирует...

>Почитал обсуждение(26 постов на момент этого), и опять не увидел - а проектировать то как? Все о кодинге да и о кодинге...

Руки не дошли пока, тем более, что проектирование -- это более сложная тема, чем кодинг :)

У меня пока есть стойкое чувство, что в при использовании функционального подхода используется старое-доброе процедурно/структурное проектирование сверху-вниз. Что делает программа? Читает аргументы командной строки, затем перебирает указанные в аргументах файлы, выбирая из такие-то данные и записывая их туда-то? Значит делаем функцию разбора аргументов, функцию перебора файлов и монаду для записи результатов. И все это приправляем острым соусом под названием "изменяемое состояние -- это белая смерть" ;)

Ой, пардонте! Функцию разбора аргументов и перебора файлом мы заменяем foldl и вспомогательным фильтром с каррингом! Мы же продвинутые функциональщики, негоже нам признаваться в том, что мы программируем в процедурном стиле ;)))

(Критиков прошу обратить внимание на количество смайликов)

eao197 комментирует...

>Хотя прекрасно войдет, и входит в ЯП "массового потребления".

Ну так и я о том же. Элементы ФП в синтаксисе Haskell-я интересны только небольшой группе хороших программистов. А вот в чуть упрощенном виде в привычном C-шном синтаксисе в каком-нибудь C# 5, Java 8 или С++2x -- будут элементарно и успешно использоваться миллионами обычных программистов.

Skynin комментирует...

У меня пока есть стойкое чувство, что в при использовании функционального подхода используется старое-доброе процедурно/структурное проектирование
Да, я помню Ваш пост. В том и мои раздумья-сомнения - рассказывать то об этом должны не новички в ФП, а адепты. Но как понял пока, из блога того же Сергея Зефирова - ФП для ряда задач по удобству сродни скриптингу (как там у него есть - "Поэтому языки семейства ML и языки типа Эрланг - это и есть серебряная пуля современности"). Или, до сих пор помню как впервые написал парсилку мудренной текстовой информации на perl'е и вспоминал мороку в более простых случаях на plain C.

сверху-вниз.
Программирование это разбиение задачи из сложной на простые. Но пока, сугубо нубское мнение от ФП - там это нужно делать всегда но просто, в императиве - конечное число раз но сложно.
В итоге - в уникальных задачах которые легко ложатся на формальные методы прикладное математики - ФП лучший выбор (оставим за скобками требуемый IQ программиста)

То есть, возможно, паттерны в ФП вообще невозможны...

Наблюдаю пока за процессом движения ФП в массы.

eao197 комментирует...

>В том и мои раздумья-сомнения - рассказывать то об этом должны не новички в ФП, а адепты.

Адептам пока нужно написать на Haskell/OCaml что-нибудь большое. Типа Eclipse или, хотя бы, Apache. А то пока весь опыт сводится к тому, что кто-то, что-то в одиночку (или небольшой группой) сделал небольшое по размеру.

Quaker комментирует...

А мне нет. Проблема выбора имен в программировании -- чуть ли не самая сложная.
Полностью согласен, иногда приходится долго думать, как лучше написать, искать синонимы и т.д.
Поэтому для достижения больших объемов потребления приходится сильно снижать порог вхождения в продукт.
У меня лично создается такое впечатление, что математики для программирования на функциональных языках придется выучить много, а вот прок от этого сомнительный. Никак не могу отделаться от ощущения, что функциональщики переизобретают велосипед, объясняя все это заумными фразами.
Вы сильно недооцениваете границы человеческой глупости и невнимательности :)
Человеческая глупость бесконечна! Быдлокодеры рано или поздно и в F# проберутся.
Вот в Eiffel есть защита и от тех, и от других. Наверное, поэтому он мало кому нравится :)
Есть мнение, что Eiffel проиграл по нетехнологическим причинам. Высокая стоимость компилятора и отсутствие длительное время бесплатной версии - вот главные преграды.
"долой олимпиадные алгоритмы"
Вот это мне тоже не нравится в функциональных ЯП - мало реальных примеров для среднестатистических программистов, ориентация на математическую элиту.
У меня пока есть стойкое чувство, что в при использовании функционального подхода используется старое-доброе процедурно/структурное проектирование сверху-вниз.
Пример с шашками в одном из номеров журнала это доказывает. В этой статье даже раздел отдельный есть "Разбиение программного кода на модули". А ведь с этого необходимо было начинать! Хорошо хоть, что само приложение было небольшим по объему. В противном случае разруливание зависимостей между модулями по окончании разработки может быть достаточно утомительным.
Адептам пока нужно написать на Haskell/OCaml что-нибудь большое. Типа Eclipse.
А вместо этого для разработки IDE под их языки они не стесняясь берут тот же Eclipse за основу. А потом удивляются: "У нас такая прекрасная математическая модель, такая стройная теория! Что же Ваша Java никак не загнется??". Смешно, да и только.
серебряная пуля современности
Считаю, что серебрянная пуля - это повторное использование кода. А функциональные ЯП, увы, к этому не располагают, являясь больше средством для программистов-одиночек.

eao197 комментирует...

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

Я сам много думал о том, почему же Eiffel не выстрелил. Названые вами причины очень важны, я с этим на 100% согласен. Но есть, имхо, и еще один фактор -- в Eiffel-е нет места для получения удовольствия от кодирования. В C++ можно замутить что-нибудь на шаблонах, в Ruby -- что-нибудь типа DSL, в Haskell -- какой-нибудь красивый функциональный наворот. Т.е. в этих языках можно действовать по принципу "Приколись, братва, как я могу!" А поскольку многие увлеченные программисты как дети, им очень нравиться играть в такие игры.

В Eiffel и Java нет места таким фокусам. Это скучные языки для скучной разработки. Но Java хорошо и вовремя пропихнули. А Eiffel нет.

Кстати, возвращаясь к обсуждаемой статье... Из нее как раз видно, какое удовольствие автор получает от "красивого" и "интересного" кода на ФЯ. Что как раз служит доказательством моего тезиса.

Quaker комментирует...

в Eiffel-е нет места для получения удовольствия от кодирования.
Возможно, нет удовольствия от написания кода на Eiffel - мало "грязных хаков" и других извращений.
Зато какое удовольствие от чтения такого кода! Какое-то ощущение простоты, ясности, совершенства, или что-то близкое к этому.
Кстати, возвращаясь к обсуждаемой статье... Из нее как раз видно, какое удовольствие автор получает от "красивого" и "интересного" кода на ФЯ.
А мне не нравится код на ФЯ - большая степень вложенности, длинные строки, много разных элементов (стрелки, скобки, вертикальная черта).

eao197 комментирует...

>Зато какое удовольствие от чтения такого кода! Какое-то ощущение простоты, ясности, совершенства, или что-то близкое к этому.

Это точно. Редко какой чужой код читается так же легко, как код на Eiffel.

>А мне не нравится код на ФЯ - большая степень вложенности, длинные строки, много разных элементов (стрелки, скобки, вертикальная черта).

В этом вы не одиноки. У меня тоже самое.

Rustam комментирует...

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

Rustam комментирует...

Руки не дошли пока, тем более, что проектирование -- это более сложная тема, чем кодинг :)

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

У меня пока есть стойкое чувство, что в при использовании функционального подхода используется старое-доброе процедурно/структурное проектирование сверху-вниз.

Вы с Владом наверно меня уговорите :) Но с существенным дополнением сладость этих языков дает новое качество, так что результат ничем ни уступает ОО декомпозиции.

Rustam комментирует...

Skynin поправка не низко а высокоуровневое :)

Rustam комментирует...

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

Я правил немало кода на питоне написанного в стиле "я немного знаю школьный паскаль" :)

Rustam комментирует...

Но как понял пока, из блога того же Сергея Зефирова - ФП для ряда задач по удобству сродни скриптингу (как там у него есть - "Поэтому языки семейства ML и языки типа Эрланг - это и есть серебряная пуля современности").

Сергей такого не мог сказать у него "Все кроме Хаскеля фигня, а если подумать то и Хаскель фигня так как там нет зависимых типов" :)

Rustam комментирует...

Адептам пока нужно написать на Haskell/OCaml что-нибудь большое. Типа Eclipse или, хотя бы, Apache. А то пока весь опыт сводится к тому, что кто-то, что-то в одиночку (или небольшой группой) сделал небольшое по размеру.

На Окамле есть достаточно большие программы например:

N:\dev\tmp\frama-c-Beryllium-20090901

ocaml: files = 1019 lines = 327612 size = 11715 kb. (11996638 bytes)


N:\dev\tmp\coq-8.2pl1

ocaml: files = 579 lines = 178173 size = 5910 kb. (6052412 bytes)


N:\dev\tmp\mldonkey-2.9.6

ocaml: files = 488 lines = 206287 size = 7293 kb. (7468237 bytes)

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

Rustam комментирует...

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

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

А вместо этого для разработки IDE под их языки они не стесняясь берут тот же Eclipse за основу.

К сожалению у них нет сотни-другой человеко-лет в запасе.

А потом удивляются: "У нас такая прекрасная математическая модель, такая стройная теория! Что же Ваша Java никак не загнется??". Смешно, да и только.

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

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

Тут ошибаешься, очень даже располагают, местами и получше ОО.

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

Тут во многом прав, но не именно одиночек, а небольших коллективов достаточно квалифицированных программистов.

Rustam комментирует...

Но есть, имхо, и еще один фактор -- в Eiffel-е нет места для получения удовольствия от кодирования. В C++ можно замутить что-нибудь на шаблонах, в Ruby -- что-нибудь типа DSL, в Haskell -- какой-нибудь красивый функциональный наворот. Т.е. в этих языках можно действовать по принципу "Приколись, братва, как я могу!" А поскольку многие увлеченные программисты как дети, им очень нравиться играть в такие игры.

Похоже микрософт это хорошо понимает, поэтому C# так развивается ну и наверно влияет то что много пользователей С# перешли на него с С++.

Rustam комментирует...

Quaker
Зато какое удовольствие от чтения такого кода! Какое-то ощущение простоты, ясности, совершенства, или что-то близкое к этому.

У меня аналогичные ощущения от хорошего кода на питоне и окамле. Так что это очень субъективно.

eao197 комментирует...

2Rustam:

>Я правил немало кода на питоне написанного в стиле "я немного знаю школьный паскаль" :)

Так именно эти программисты и пишут подавляющее большинство кода. И с этим нужно считаться.

>Все эти программы по моему занимали бы больше миллиона строк на С++ или яве.

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

Во-вторых, тот же Eclipse -- это более 25M строк кода. Даже если ФЯ дают код в пять раз компактнее, то это 5M строк. Потянут ли ФЯ проекты таких размеров с таким количеством разработчиков? Терзают меня смутные сомнения, в особенности из-за того, что код на ФЯ пишется в обобщенном стиле.

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

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

Как с этой сложностью справляться в ФЯ -- ХЗ. Слишком много противоречий с внешним миром (одна иммутабельность чего стоит).

Поэтому я бы не стал противопоставлять ОО проектирование и ФЯ кодирование.

Quaker комментирует...

Вся нужная математика изучается на первых курсах ВУЗов. Программисты уж точно ее изучают.
Вряд ли студент среднего по уровню технического вуза сможет внятно объяснить Вам, что такое функция высшего порядка, замыкание, карринг, свертка и т.д. Да что там студент - думаю, эти понятия и многим профессиональным программистам не слишком хорошо знакомы.
К сожалению у них нет сотни-другой человеко-лет в запасе.
Чем же так упорно занимаются функциональщики, раз даже времени на IDE нет? Придумыванием очередных математически заумных фраз? А сами хвастаетесь сокращением в несколько раз временных затрат на написание кода и количества написанных строк.

Skynin комментирует...

Сергей такого не мог сказать
ссылка на первоисточник
Можно и с первой страницы его блога - Рубрика Самое интересное: "Серебряная пуля есть".
Rustam, не надоело "кусаться"?

Rustam комментирует...

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

Я тоже так думал, но тут http://www.rsdn.ru/forum/philosophy/2766286.flat.aspx#2766286 на примерах вполне достаточно объема мне показали что я ошибаюсь.

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

Во-вторых, тот же Eclipse -- это более 25M строк кода. Даже если ФЯ дают код в пять раз компактнее, то это 5M строк. Потянут ли ФЯ проекты таких размеров с таким количеством разработчиков? Терзают меня смутные сомнения, в особенности из-за того, что код на ФЯ пишется в обобщенном стиле.

Думаю про ООП тоже самое говорили, про C++ относительно Си я это точно слышал.

Как с этой сложностью справляться в ФЯ -- ХЗ. Слишком много противоречий с внешним миром (одна иммутабельность чего стоит).

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

Поэтому я бы не стал противопоставлять ОО проектирование и ФЯ кодирование.

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

Rustam комментирует...

Quaker

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

Зато он должен знать что такое лямбда, рекурсивные и частично-рекурсивные функции, функционалы и операторы. С этими знаниями не понять то что у тебя выше просто невозможно.

Чем же так упорно занимаются функциональщики, раз даже времени на IDE нет?

На форумах и блогах флудят конечно.
А если серъезно есть ли в ФЯ такая же необходимость в навороченных IDE как для явы? Ответ простой нет, языки достаточно мощные чтобы обходится без костылей. Ну и другой вопрос зачем тратить колоссальное время на написание мало востребованного приложения на "родном" языке, когда это можно намного быстрее сделать на специально для этого предназначенном инструментарии.

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

100 или 1000 человеко лет даже в несколько раз сокращенные остаются гигантским сроком.

Rustam комментирует...

Skynin тык когда это было, сейчас все так как я описал :)

Rustam, не надоело "кусаться"?

Странный вопрос :)
Не я же начал. Да и это разве кусаться :)
А так я всегда за мир во всем мире.

eao197 комментирует...

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

Ну и хорошо, если будет так.

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

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

eao197 комментирует...

>А если серъезно есть ли в ФЯ такая же необходимость в навороченных IDE как для явы? Ответ простой нет, языки достаточно мощные чтобы обходится без костылей.

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

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

Rustam комментирует...

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

В результате получится OCaml с сишным синтаксисом :)

Ну так гибриды и будут рулить. Тот же OCaml и F# же не чистые ФЯ а гибриды.

Rustam комментирует...

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

Так ведь IDE уже есть например для OCaml'а и F# просто написаны с использованием не кошерных технологий, и это кое-кому очень почему-то не нравится :)

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

Баг трекинг обычно в браузере, VCS интегрирован в оболочку OS (черепашка) или отдельное приложение, никакой необходимости в интеграции всего этого в IDE даже для C++ я не вижу.

eao197 комментирует...

>В результате получится OCaml с сишным синтаксисом :)

Кстати, да -- был бы у окамла C-шныцй синтаксис, изучать его было бы гораздо проще. По себе знаю, насколько ломает разбираться с языком, в котором сущности объявляются как let x in ...;

Ну а основной мой поинт в том, что проникновение ФЯ в мейнстрим возможно двумя путями:

1. Популяризация OCaml/Haskell/F# и чего-то им подобного.

2. Расширение традиционных императивных языков функциональными конструкциями (вроде Scala и элементов ФЯ в C#, C++ и D).

Так вот второй путь, имхо, более вероятен и оправдан.

eao197 комментирует...

>никакой необходимости в интеграции всего этого в IDE даже для C++ я не вижу.

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

Rustam комментирует...

Так вот второй путь, имхо, более вероятен и оправдан.

Пока практика показывает что более вероятен первый путь, Ms подержало почему-то F# а не Немерли.

Хотя конечно и Немерли и Scala скорее третий путь.

eao197 комментирует...

>Пока практика показывает что более вероятен первый путь, Ms подержало почему-то F# а не Немерли.

Пока для меня F# выглядит как попытка MS привлечь на .NET функциональщиков. Для экспериментов по улучшению самого .NET. Куда пойдут результаты этих экспериментов -- нужно будет еще посмотреть.

А почему F, а не N... Возможно, просто более близкие к MS люди занимались F.

Rustam комментирует...

Я наблюдаю стремительный рост коммьюнити вокруг F#, по моему даже если MS охладеет к нему он все равно повторит путь питона - руби но гораздо быстрее, в любом случае около мейнстрима (скажем как недавно тот же питон) он точно будет.

С Наступающим! :)

Skynin комментирует...

Я наблюдаю стремительный рост коммьюнити вокруг F#
Так как основной мой ЯП последний год - C#, "тусуюсь" среди дотнетчиков.
Фактом роста комьюнити вокруг F# удивлен, потому что не приметил. Хотя, если этот рост обеспечивается переходом с OCaml и Хаскеля, как предположил Евгений - "привлечение функциональщиков", то почему б и нет, наверное "растет" - изначальные функциональщики меняют платформу.

он все равно повторит путь питона - руби но гораздо быстрее
Причины популярности питона и руби - иные, чем предполагаемые у "OCaml for .NET". Начиная от целевой аудитории и заканчивая областью применения.
Расширение ассортимента и популярность - не одно и тоже. От Nemerle же MS отказались - как понимаю, в силу слишком новаторских там решений. Им скорей для галочки - а вот желающим и ФЯ для .NET - нужен был язык. Вот и взяли проверенный OCaml.

Будет ли популяризировать MS F#? А зачем им это нужно? Им нужно как можно бОльшее число разработчиков для приложений под свою ОСь, и на своих инструментах. А уж на каком ЯП - им без разницы.

beroal комментирует...

jkff пишет:
Конструктивной критики очень не хватает; как-то больше придираются к верстке или к тому, что "че-то в общем и целом как-то сложновато, лень было вчитываться".

Думаю, что конструктивная критика невозможна. Если из теории программирования удалить математику, то останется софистика и религия. Ну и придирки получаются соответствующего рода. И сводятся в конце концов к волюнтаризму, то есть "моей левой ноге это не понравилось". ;)

Skynin комментирует...

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

Есть вера в Математику. Весьма догматическая религия.

Недавно понравился рассказ Теда Чана "Деление на ноль"...

beroal комментирует...

Программирование уже давно стало самостоятельной областью, со своей теорией ремесла.
Это не противоречит тому, что я сказал. Если вычесть из этой теории ремесла… и далее по тексту. Рассказ, конечно, интересный, но по-моему о догматической вере в математику там не говорится. Самоубийства характерны для всех профессий и даже для людей без профессий. ;)

Skynin комментирует...

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

Это соответствует и моему профессиональному опыту программиста. И наблюдениями за коллегами.

beroal комментирует...

дисциплиной, интересующейся написанием компьютерных программ
Вот эта «дисциплина» и является софистикой+религией.

Skynin комментирует...

Вот эта «дисциплина» и является софистикой+религией.
Теперь понятней Ваша терминология :)
С точки зрения фундаментальной науки наверное вся инженерия сплошь шаманское ремесло :)
Вполне согласен, что если оттудова, свысока-издалека смотреть, то ..., удивительно как вообще хоть что-то можно разглядель типа софистики+религии :)

Я тут более фундаментальную вещь вспомнил. про математический догматизм - "МЫ" Е. Замятина :)

[DiMa] комментирует...

Книг по использованию ФП вполне хватает. Причем наиболее ценные из них имеют уже изрядную историю

Я не мэйнстрим девелопер и мне например GoF и её "ценность" и т.д. и т.п. весьма сомнтиельны. По этому поводу есть хорошо известная презентация http://norvig.com/design-patterns/ppframe.htm - то есть перенос не столько не возможен сколько не нужен.

Вообще мэйнстимность инструмента очень странное понятие...

eao197 комментирует...

2[DM]:

>Я не мэйнстрим девелопер и мне например GoF и её "ценность" и т.д. и т.п. весьма сомнтиельны.

Мне тоже.

>Вообще мэйнстимность инструмента очень странное понятие...

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