Заинтересовался сабжем, в частности Clojure и прочими лиспоподобными. В разных книжках и статьях утверждается, что программы на функциональных языках короче и понимабельнее, чем на императивных. Но вот эту мысль я никак не могу понять - каким образом реализация алгоритмов (особенно сложных) на функциональных языках проще и понятнее? Пока складывается впечатление, что это языки-головоломки, а не удобные средства построения абстракций и DSL... Кто-нибудь может просветить или дать линк на хорошую статью?
Типа чистые функции без побочных эффектов(пальцы веером), никаких циклов, декларативный стиль программирования, когда мы объясняем что хотим получить, а не то как это получить, в общем ересь(шутка). DSL как правило это утопия.
Я конкретно серьезно Построение domain specific languages и использование их в программировании и настройке программной системы - это одно из современных направлений развития, все модные динамические языки пытаются включать в себя средства, позволяющие описывать данные кодом с минимальным количеством синтаксического мусора. И я видел утверждения, что лисп и его потомки лучше всего подходят для такого дела... но как дело дошло до изучения, в упор не вижу, каким образом можно писать большие программы с высоким уровнем абстрагирования... Вот, может кто в курсе или знает статью, прочищающую мозг в нужную сторону
Booster Ты не совсем прав - вот 2 примера удачного использования DSL И у меня есть личный опыт удачного применения DSL в проекте (на основе Groovy) http://en.wikipedia.org/wiki/Business_Process_Execution_Language http://en.wikipedia.org/wiki/Drools
Одно дело когда строят конкретную dsl для конкретной задачи и другое, когда стремятся построить универсальную. Это больше от прослойки между стулом и компом зависит. Архитектура приложения это и есть dsl. Большие комплексы так и строятся, компоненты более высокого уровня используют низкоуровневые.
Booster Универсальный dsl - это взаимоисключающие параграфы: смысл dsl в том, что он пригоден для одной конкретной задачи. Насчет архитектуры и dsl ты абсолютно прав, тут вопрос в том, что подходит наилучшим образом в качестве dsl - код на сях/яве/другом универсальном языке, вызывающий уже написанные функции/модули? - свой синтаксис с нуля на бизоне или ANTLR? - универсальный императивный язык с минималистичным синтаксисом + перегрузка и подмена чего угодно + манипуляции с AST? - лисп с его "код = данные" ? - что-то еще? Это конкретный, практический вопрос, имеющий конкретную, практическую применимость... edit: С++ - это тоже хороший пример DSL. На шаблонах можно создать любую абстракцию и потом ей пользоваться без лишнего синтаксического мусора. Но с ним проблема в том, что сломаешь мозг, пока реализуешь DSL на плюсах... шаблоны - это не самая простая штука.
Нет. Бизон и подобные кодогенераторы и есть пример удачного dsl. А хрен его знает, каждый хвалит своё болото. Но вообще конечно нужно выбирать наиболее подходящее средство, но какое оно - наверняка никто не знает. Язык программирования общего назначения это не dsl, а средство для его написания.
scf Несмотря на то, что на парах меня (студентов) старательно пытались убедить в обратном, я всё ещё считаю, что с чисто функциональными языками стоит познакомиться только в общеобразовательных целях, а их применение на практике серьёзно затруднено идеалистическими ограничениями (хотя существует приличное количество проектов, которые свидетельствуют об обратном). Например, потенциально императивный ввод-вывод реализуется посредством довольно трудноосознаваемых монад. Или, например, одна из простейших (и наиболее важных) структур — очередь. Попробуйте реализовать очередь на том же Haskell так, чтобы как enque, так и deque имели константную сложность (в си это всего лишь заиметь два указателя: на начало и конец очереди). Из плюсов очень впечатляюще смотрятся техники написания програм посредством нескольких инвариантных преобразований: написал на листочке спецификацию того, что нужно, сделал пару преобразований и получил готовый программный код, ещё пару преобразований, и получи оптимизированную версию. Причём эти техники автоматизируются.
l_inc Большинство современных функциональных языков не впадают в крайности и позволяют использовать либо мутаторы(изменяющиеся переменные), либо сайд эффект скрывается в глубинах библиотеки, а наружу торчит красивая обертка (привет хаскель). В том же Clojure F# можно пользоваться всеми прелестями jre/.net библиотеки. Лисп не pure functional и при острой оптимизационной зависимости можно прямо на inline c/assembler функции писать, есть возможность подключать через FFI сишные библиотеки. http://ecls.sourceforge.net/new-manual/re14.html Как по мне, если количество элементов очереди меньше 1000 можно спокойно пользоваться обыкновенным списком. Как только появляется большое количество элементов или специализированные выборки сразу подключаю in-memory базу данных. По поводу алгоритмов, тут все зависит от задачи и пишущего. Предпочтительный вариант выбирать язык под задачу а не наоборот. Один раз был спор кто красивее сделает функцию определения покерных рук. Тк спорили два хакера, каждый использовал свою магию и никто не провалился. scf, рекомендую решить эту задачу на твоем любимом языке ) В процессе решения/отладки в текстовом файле записывай ошибки которые ты допустил, пишешь, допустим, строку кода и причину ошибки. Можешь еще записывать время которое ты потратил на поиск ошибки. Получишь очень забавную статистику, сразу будет видно где тебя подвел язык, а где код писался после работы в а###асе. http://en.wikipedia.org/wiki/List_of_poker_hands