Я читал книгу Doets и Eijck «Дорога к логике, математике и программированию на Haskell», написанную Doets и Eijck 2004. Кажется, это очень уважаемая книга, но я был поражен, когда в ней утверждается, что Haskell является членом семейства Lisp. Это точно? Я бы охарактеризовал Лисп с s-выражениями, нечистыми функциями и списками как единственную составную структуру данных. В Haskell ничего этого нет. Какое обоснование этому утверждению?
Является ли Haskell Лиспом?
Ответы (9)
Лисп — очень расплывчатое понятие. Я вижу два более-менее полезных толкования:
Лисп как семейство языков, которые имеют некоторые общие идеи. В широком понимании к этому семейству относятся очень разные языки: Common Lisp, Scheme, Logo, Dylan, Emacs Lisp, Clojure, RLisp, 3Lisp и многие-многие другие.
Lisp как родословная языков, которые так или иначе реализуют основной язык (CAR, CDR, CONS, LAMBDA, PROG, SET, SETQ, QUOTE, DEFUN, IF, COND, DO, ...): Lisp 1.5, MacLisp, Lisp Machine Лисп, Emacs Лисп, Коммон Лисп, ISLisp. Обратите внимание, что в названии этих языков обычно есть слово «Lisp».
Некоторые типичные вещи, которые мы находим в диалектах Лиспа: строгое вычисление, побочные эффекты, прямое императивное программирование, конструкции функционального программирования, s-выражения, вычисление, макросы.
Haskell — это совсем другой язык: нестрогие вычисления, синтаксис, не основанный на s-выражениях, статическая типизация, чисто функциональный.
Haskell не подходит ни для 1, ни для 2. Так что я бы сказал, что Haskell — это не Lisp.
Аналогично, мы можем сказать, что язык функционального программирования:
язык, поддерживающий функциональное программирование: Lisp, APL,..., ML, SML, OCAML, F#, Miranda, Haskell,...
язык, который обеспечивает функциональное программирование. Здесь Лисп уже не особо подходит, так как императивное или даже объектно-ориентированное программирование не является в Лиспе вторым сортом.
язык, который обеспечивает чистое функциональное программирование. Здесь у нас есть Haskell в качестве хорошего примера. Как относительно новый диалект Lisp, Clojure также может подойти.
Обычно Lisp только поддерживает, но не навязывает функциональное программирование. Так что это функциональный язык программирования в более широкой интерпретации.
Haskell — один из языков, который считается чисто функциональным языком программирования.
Я думаю, что с натяжкой рассматривать Haskell как члена семейства LISP, но я подозреваю, что рассуждения выглядят примерно так...
При классификации языков программирования имеет смысл разделить их на две группы: производные от FORTRAN и не являющиеся потомками. В 1958 году группа не FORTRAN в значительной степени означала LISP (по крайней мере, среди языков, которые не вымерли сегодня). Итак, какое-то время генеалогическое древо языков программирования имело две основные ветви: потомки FORTRAN и потомки LISP. Если это единственные два варианта, я бы поместил Haskell в ветку LISP.
Тем не менее, многие комментаторы считают, что такие языки, как ML, Prolog и APL, возникли на ровном месте, представив достаточно разные парадигмы, чтобы заслужить собственное происхождение. Haskell явно связан с ML.
В качестве примеров таких классификаций см. следующие семейные деревья языков программирования:
Плакат O'Reilly по языку программирования
Хронология компьютерных языков на сайте levenez.com
HOPL: интерактивный список языков программирования (вход на Haskell)
Я бы не согласился с этим. Оба они являются функциональными языками программирования, и Lisp повлиял на Haskell, но Haskell не является производным от Lisp. Просто посмотрите на количество скобок, и вы все поймете.
То, что люди определяют как шепелявость, варьируется. Первоначальная спецификация лиспа вообще не упоминала макросы и определяла лишь небольшой список примитивных функций, которые, если мне не изменяет память, следующие:
cons
car
cdr
cond
eq
atom
and
or
not
nil
Это может быть неполный список или в нем может быть несколько дополнительных членов, но в любом случае Первоначальная спецификация Джона Маккарти была очень маленькой.
Если вы определяете lisp как любой язык, который определяет все эти функции, то большинство современных языков, включая haskell, являются lisp.
Более строгое и современное определение шепелявости выглядит следующим образом:
- нетерпеливая оценка
- динамическая типизация
- нечистый функционал
- макросы
- сосредоточиться на списках как на первичной структуре данных
Haskell не подходит к первым трем, его макросы (шаблон haskell) не следуют парадигме код-данные, и хотя списки очень важны, они не являются основной структурой данных.
Так что я бы сказал нет, Haskell не шепелявит.
Я думаю, что Haskell является Лиспом в том смысле, что они оба основаны на λ-исчислении. Haskell — это реализация λ.
Хотя большинство людей сказали бы, что Haskell принадлежит к семейству ML. ML также основан на λ, как и все известные мне функциональные языки.
Под капотом OCam (потомок ML) скомпилирован в комбинаторную логику, формализм, эквивалентный λ-исчислению, и был изобретен Хаскеллом Карри, логиком, в честь которого назван Haskell. Но использование комбинаторной логики для компиляции функционального языка в настоящее время кажется менее популярным, поэтому я не уверен в современных компиляторах, таких как GHC.
Синтаксис Lisp почти идентичен λ-исчислению, что делает это семейство (Scheme, Clojure и т. д.) особенным.
Хаскель, конечно, не лисп. У каждого свое понимание того, что такое, черт возьми, "сюсюканье". IMHO lisp - это язык, исходный код которого является допустимой структурой на том же языке. Исходный код Haskell не является допустимой структурой в haskell, поэтому они должны иметь отдельный синтаксис (шаблон Haskell) для управления собственным исходным кодом.
Но в haskell есть по крайней мере одна интересная особенность, которая напоминает мне lisp. Это синтаксис вызовов функций: func args1 agr2 arg3. Лисп имеет ТОЧНО такой же синтаксис: (func args1 agr2 arg3). На самом деле вы можете включать внешние скобки и в haskell. Все остальные языки семейства алголов вводят скобки и запятые между именем функции и аргументами.
Я бы сказал, что оба являются функциональными языками, что делает их принадлежащими к одной семье. Однако я бы не назвал Haskell производным от Lisp (как Scheme).
Можно утверждать, что все функциональные языки являются потомками Scheme в той мере, в какой Scheme грубо наткнулся на реализацию лямбда-исчисления (хотя и с причудами), а функциональные языки также реализуют лямбда-исчисление, хотя они не обязательно всегда выглядят так. Кроме того, возможно, родословная ML совершенно отлична, потому что она восходит к ISWIM Ландина, который был влиятельным, но так и не был реализован, имел очень мало общего с Lisp и с самого начала знал его теоретические основы.
На самом деле, однако, Haskell и Lisp имеют гораздо больше общего друг с другом, чем с семейством C или семейством Prolog.
Я бы сказал, что людям следует не обращать внимания на синтаксические проблемы, но я забыл, что лисперы определяют синтаксис как ключевую часть того, что значит быть шепелявым. Что я считаю глупым, потому что, возможно, Haskell — это не Lisp, а Liskell, хотя последний и является в основном процессор для первого.
Хойт сравнивает некоторые языки и утверждает, что Haskell НЕ является Лиспом, потому что он слишком строг в отношении типов и предназначен только для ученых, тогда как Common Lisp больше похож на язык прототипирования (без строгости, динамическая типизация).
См.: Let Over Lambda — 50 Years of Lisp Дуга Хойта (продвинутая книга о Common Lisp, http://letoverlambda.com/< /а>)
Haskell и Common Lisp (вероятно, все Lisp) оптимизированы для парадигмы функционального программирования (FP). Haskell чист, тогда как Common Lisp нечист. Сравните термин FP также с «полным функциональным программированием».
Также взгляните на эту диаграмму, сравнивающую парадигмы языков программирования: http://www.info.ucl.ac.be/~pvr/paradigms.html