Для тех из вас, кто имел опыт работы как с Haskell, так и с некоторыми разновидностями Lisp, мне любопытно, насколько «приятно» (если использовать ужасный термин) писать код на Haskell и Lisp.
Немного предыстории: сейчас я изучаю Haskell, раньше работал со Scheme и CL (и немного углубился в Clojure). Традиционно меня можно было считать поклонником динамических языков за их краткость и скорость. Я быстро влюбился в макросы Lisp, поскольку они дали мне еще один способ избежать многословия и шаблонности.
Я нахожу Haskell невероятно интересным, поскольку он знакомит меня со способами программирования, о существовании которых я не подозревал. В нем определенно есть некоторые аспекты, которые, как кажется, могут помочь в достижении гибкости, например, простота написания частичных функций. Однако меня немного беспокоит потеря макросов Lisp (я предполагаю, что теряю их; правда, я, возможно, просто еще не узнал о них?) И систему статической типизации.
Не мог бы кто-нибудь, кто сделал приличное количество кода в обоих мирах, прокомментировать, чем отличается опыт, что вы предпочитаете, и если это предпочтение является ситуативным?
источник
Прежде всего, не беспокойтесь о потере определенных функций, таких как динамический набор текста. Поскольку вы знакомы с Common Lisp, чрезвычайно хорошо разработанным языком, я предполагаю, что вы знаете, что язык нельзя свести к его набору функций. Все дело в едином целом, не так ли?
В этом отношении Haskell сияет так же ярко, как и Common Lisp. Сочетание его функций дает вам способ программирования, делающий код чрезвычайно коротким и элегантным. Отсутствие макросов несколько смягчается более сложными (но также более сложными для понимания и использования) концепциями, такими как монады и стрелки. Система статических типов увеличивает ваши возможности, а не мешает вам, как в большинстве объектно-ориентированных языков.
С другой стороны, программирование на Haskell намного менее интерактивно, чем на Lisp, и огромное количество отражений, присутствующих в таких языках, как Lisp, просто не соответствует статическому взгляду на мир, который предполагает Haskell. Поэтому доступные вам наборы инструментов для двух языков сильно различаются, но их трудно сравнивать друг с другом.
Я лично предпочитаю Lisp-метод программирования в целом, так как я считаю, что он лучше подходит для моей работы. Однако это не означает, что вы тоже обязаны это делать.
источник
В Haskell меньше необходимости в метапрограммировании, чем в Common Lisp, потому что многое можно структурировать вокруг монад, а добавленный синтаксис делает встроенные DSL менее древовидными, но всегда есть Template Haskell, как упоминалось ShreevatsaR , и даже Liskell (семантика Haskell + Lisp синтаксис), если вам нравятся круглые скобки.
источник
Что касается макросов, вот страница, на которой рассказывается об этом: Hello Haskell, Goodbye Lisp . Это объясняет точку зрения, согласно которой макросы в Haskell просто не нужны. Для сравнения прилагается небольшой пример.
Пример случая, когда требуется макрос LISP, чтобы избежать оценки обоих аргументов:
Пример случая, когда Haskell не оценивает систематически оба аргумента без необходимости в каком-либо макроопределении:
И вуаля
источник
delay
может быть функцией.accept
это (E) DSL.accept
Функция является аналогом макроса , изложенным на предыдущих страницах, а также определениеv
в точности параллельно с определениемv
в схеме на слайде 40. Функция Haskell и Scheme вычислить то же самое , с той же самой стратегией оценки. В лучшем случае макрос позволяет вам раскрыть оптимизатору большую часть структуры вашей программы. Вряд ли вы можете назвать это примером, когда макросы увеличивают выразительную силу языка способом, который не воспроизводится ленивым вычислением.automaton
становитсяletrec
,:
становитсяaccept
,->
становится ничем). Без разницы.Я программист на Common Lisp.
Некоторое время назад я попробовал Haskell, и в итоге я решил придерживаться CL.
Причины:
У Haskell, конечно, есть свои достоинства, и некоторые вещи он делает принципиально по-другому, но в долгосрочной перспективе он меня не решает.
источник
dilbert = dogbert.hire(dilbert);
" ?? Я сомневаюсь, что многие программисты на Haskell могут даже прочитать это, даже не дергаясь.В Haskell вы можете определить функцию if, что невозможно в LISP. Это возможно из-за лени, которая делает программы более модульными. В этой классической статье Джона Хьюза « Почему важны FP » объясняется, как лень улучшает компоновку.
источник
fold
, например , в то время как нестрогие функции делают .Есть действительно интересные вещи, которых вы можете достичь в Лиспе с помощью громоздких (если возможно) макросов в Haskell. Возьмем, к примеру, макрос «memoize» (см. Главу 9 PAIP Питера Норвига). С его помощью вы можете определить функцию, например foo, а затем просто оценить (memoize 'foo), которая заменяет глобальное определение foo мемоизированной версией. Можете ли вы добиться того же эффекта в Haskell с помощью функций высшего порядка?
источник
По мере того, как я продолжаю свое путешествие по изучению Haskell, мне кажется, что одна вещь, которая помогает «заменить» макросы, - это способность определять свои собственные инфиксные операторы и настраивать их приоритет и ассоциативность. Довольно сложная, но интересная система!
источник