it-roy-ru.com

Haskell, LISP и многословие

Для тех из вас, кто имел опыт как в Haskell, так и в некотором роде LISP, мне любопытно, насколько "приятно" (если использовать ужасный термин) писать код на Haskell против LISP.

Немного предыстории: сейчас я изучаю Haskell, раньше работал с Scheme и CL (и немного разбираюсь в Clojure). Традиционно вы можете считать меня поклонником динамических языков за краткость и скорость, которую они обеспечивают. Я быстро влюбился в макросы LISP, поскольку это дало мне еще один способ избежать многословия и шаблонов.

Я нахожу Haskell невероятно интересным, поскольку он знакомит меня с способами кодирования, о которых я не знал, что они существуют. У него определенно есть некоторые аспекты, которые, кажется, помогут в достижении гибкости, такие как простота написания частичных функций. Тем не менее, я немного обеспокоен потерей макросов LISP (я полагаю, я их потеряю; правда, я могу сказать, что я, возможно, еще не узнал о них?) И системой статической типизации.

Будет ли кто-нибудь, кто проделал приличное количество кодирования в обоих мирах, возразить, комментируя, как различается опыт, который вы предпочитаете, и если указанное предпочтение является ситуативным?

103
J Cooper

Короткий ответ:

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

[Примечание: есть " Template Haskell ", который позволяет вам писать макросы так же, как в LISP, но, строго говоря, вам никогда не нужно Это.]

68
ShreevatsaR

Прежде всего, не беспокойтесь о потере определенных функций, таких как динамическая типизация. Поскольку вы знакомы с Common LISP, удивительно хорошо разработанным языком, я предполагаю, что вы знаете, что язык не может быть сведен к его набору функций. Это все о целостном целом, не так ли?

В этом отношении Haskell сияет так же ярко, как и Common LISP. Его функции объединяются, чтобы предоставить вам способ программирования, который делает код чрезвычайно коротким и элегантным. Отсутствие макросов несколько смягчается более сложными (но также более сложными для понимания и использования) понятиями, такими как монады и стрелы. Система статических типов добавляет вам силы, а не мешает, как в большинстве объектно-ориентированных языков.

С другой стороны, программирование на Haskell намного менее интерактивно, чем LISP, и огромное количество отражений, присутствующих в таких языках, как LISP, просто не вписывается в статический взгляд на мир, который предполагает Haskell. Таким образом, доступные вам наборы инструментов сильно различаются между двумя языками, но их трудно сравнивать друг с другом.

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

63
Matthias Benkard

В Haskell меньше необходимости в метапрограммировании, чем в Common LISP, потому что многое может быть структурировано вокруг монад, а добавленный синтаксис делает встроенные DSL менее древовидными, но всегда есть Template Haskell, как указано в ShreevatsaR , и even Liskell (семантика Haskell + синтаксис LISP), если вам нравятся круглые скобки.

13
Herrmann

Что касается макросов, вот страница, на которой об этом говорится: Здравствуйте, Haskell, Goodbye LISP . Это объясняет точку зрения, где макросы просто не нужны в Haskell. Это идет с коротким примером для сравнения.

Пример случая, когда требуется макрос LISP, чтобы избежать оценки обоих аргументов:

(defmacro doif (x y) `(if ,x ,y))

Пример, в котором Haskell систематически не оценивает оба аргумента без необходимости что-либо вроде определения макроса:

doif x y = if x then (Just y) else Nothing

И вуаля

10
Hibou57

Я обычный программист LISP.

Попробовав Haskell некоторое время назад, мой личный итог был в том, чтобы придерживаться CL.

Причины:

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

У Haskell, конечно, есть свои достоинства, и он делает некоторые вещи совершенно по-другому, но для меня это просто не в долгосрочной перспективе.

8
Leslie P. Polzer

В Haskell вы можете определить функцию if, что невозможно в LISP. Это возможно из-за лени, которая учитывает большую модульность в программах. Этот классический документ: Почему FP имеет значение Джона Хьюза, объясняет, как лень улучшает сочетаемость.

6
luntain

Есть действительно классные вещи, которых вы можете достичь в LISP с помощью макросов, которые громоздки (если это возможно) в Haskell. Возьмем, к примеру, макрос "memoize" (см. Главу 9 PAIP Питера Норвига). С его помощью вы можете определить функцию, скажем, foo, а затем просто выполнить оценку (memoize 'foo), которая заменяет глобальное определение foo на записанную версию. Можете ли вы добиться того же эффекта в Haskell с функциями высшего порядка?

4
user170889

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

4
J Cooper