私は Doets と Eijck による The Haskell Road to Logic, Maths and Programming 2004 を読んでいます。これは評判の良い本のようですが、Haskell が Lisp ファミリーのメンバーであると書かれているのには衝撃を受けました。これは正確ですか?Lisp は、S 式、不純な関数、およびリストを唯一の複合データ構造として特徴付けることができます。Haskellにはそれがありません。その主張にはどのような根拠がありますか。
9 に答える
Lisp は非常に曖昧な概念です。多かれ少なかれ有用な解釈が 2 つあります。
いくつかの共通のアイデアを共有する言語のファミリーとしての Lisp。広い解釈では、Common Lisp、Scheme、Logo、Dylan、Emacs Lisp、Clojure、RLisp、3Lisp など、さまざまな言語がこのファミリーに属しています。
何らかの形でコア言語 (CAR、CDR、CONS、LAMBDA、PROG、SET、SETQ、QUOTE、DEFUN、IF、COND、DO、...) を実装している言語の系譜としての Lisp: Lisp 1.5、MacLisp、Lisp Machine Lisp、Emacs Lisp、Common Lisp、ISLisp。これらの言語には通常、名前の一部に「Lisp」が含まれていることに注意してください。
Lisp の方言に見られる典型的なもの: 厳密な評価、副作用、直接命令型プログラミング、関数型プログラミング構造、s 式、評価、マクロ。
Haskell は非常に異なる言語です。厳密でない評価、s 式の上に基づかない構文、静的型付け、純粋に関数型です。
Haskell は 1 にも 2 にも適合しません。つまり、Haskell は Lisp ではないと言えます。
同様に、関数型プログラミング言語は次のように言えます。
関数型プログラミングをサポートする言語: Lisp、APL、...、ML、SML、OCAML、F#、Miranda、Haskell、...
関数型プログラミングを強制する言語。命令型プログラミングやオブジェクト指向プログラミングでさえ、Lisp の 2 番目のクラスではないため、ここで Lisp はすでに実際には適合しません。
純粋関数型プログラミングを強制する言語。ここでは Haskell が良い例です。比較的新しい Lisp の方言として、Clojure も適合する可能性があります。
通常、Lisp は関数型プログラミングをサポートするだけで、強制はしません。したがって、より広い解釈では関数型プログラミング言語です。
Haskell は、純粋関数型プログラミング言語と見なされる言語の 1 つです。
Haskell を LISP ファミリーのメンバーと見なすのは無理があると思いますが、その理由は次のようになると思います...
プログラミング言語を分類する場合、FORTRAN 系とそうでない系の 2 つのグループに分けることが重要です。1958 年には、「非 FORTRAN グループ」はほとんど LISP を意味していました (少なくとも、今日絶滅していない言語の中で)。そのため、しばらくの間、プログラミング言語のファミリー ツリーには、FORTRAN の子孫と LISP の子孫という 2 つの主要なブランチがありました。この 2 つの選択肢しかない場合は、Haskell を LISP ブランチに入れます。
しかし、多くのコメンテーターは、ML、Prolog、APL などの言語が「突然」発生したと考えています。Haskell は明らかに ML に似ています。
このような分類の例として、次のプログラミング言語ファミリー ツリーを参照してください。
私はそれに同意しません。どちらも関数型プログラミング言語であり、Lisp の影響を受けた Haskell ですが、Haskell は Lisp の派生物ではありません。括弧の量を見ればわかります。
Haskellは両方ともラムダ計算に基づいているという意味でLispだと思います。Haskellはλの実装です。
ほとんどの人はHaskellはMLファミリーに属していると言うでしょうが。私が知っているすべての関数型言語と同様に、MLもλに基づいています。
内部的には、OCam(MLから派生)は、λ計算に相当する形式であるコンビネータ論理にコンパイルされ、Haskellの名前にちなんで名付けられた論理学者であるHaskellCurryによって発明されました。しかし、機能言語のコンパイルにコンビネータ論理を使用することは、最近ではあまり一般的ではないように思われるため、GHCのような最新のコンパイラについてはよくわかりません。
Lispの構文はλ計算とほとんど同じであるため、このファミリ(Scheme、Clojureなど)は非常に特別です。
人々がリスプとして定義するものはさまざまです。Lisp の元の仕様では、マクロについてはまったく言及されておらず、プリミティブ関数の小さなリストしか定義されていませんでした。
cons
car
cdr
cond
eq
atom
and
or
not
nil
これは完全なリストではないか、追加メンバーがほとんどない可能性がありますが、いずれにせよ、John McCarthy の元の仕様は非常に小さいものでした。
これらすべての関数を定義する任意の言語として Lisp を定義すると、haskell を含むほとんどの最新の言語は Lisp になります。
Lisp のより厳密で現代的な定義は次のとおりです。
- 熱心な評価
- 動的型付け
- 不純な機能
- マクロ
- 主要なデータ構造としてリストに焦点を当てる
Haskell は最初の 3 つに適合しません。それはマクロ (テンプレート haskell) が code-is-data パラダイムに従っていないことです。リストは非常に重要ですが、主要なデータ構造ではありません。
Haskell は Lisp ではありません。
Haskell はもちろん Lisp ではありません。誰もが「lisp」とは何かを独自に理解しています。IMHO Lisp は、ソース コードが同じ言語で有効な構造である言語です。Haskell のソース コードは haskell では有効な構造ではないため、独自のソース コードを操作するには別の構文 (Haskell テンプレート) が必要です。
しかし、haskell には、Lisp を思い起こさせる興味深い機能が少なくとも 1 つあります。関数呼び出しの構文: func args1 agr2 arg3. Lisp の構文はまったく同じです: (func args1 agr2 arg3)。実際、haskele にも外側の括弧を含めることができます。他のすべての algol ファミリ言語では、関数名と引数の間に括弧とコンマが導入されています。
どちらも関数型言語であり、同じファミリーに属していると言えます。ただし、Haskell を Lisp の派生物 (Scheme など) とは呼びません。
ほぼ間違いなく、すべての関数型言語は、Scheme が大まかにラムダ計算を実装する (癖はありますが) という点で、Scheme の子孫であり、関数型言語もラムダ計算を実装しますが、必ずしもそのように見えるとは限りません。また、ほぼ間違いなく、ML 系統は完全に異なるものです。それは、影響力はあったものの実装されなかった Landin の ISWIM にまでさかのぼり、Lisp とはほとんど関係がなく、最初からその理論的基礎を知っていたからです。
しかし実際には、Haskell と Lisp には、C ファミリーや Prolog ファミリーよりもはるかに多くの共通点があります。
私は人々が構文上の問題に目を向けるべきだと主張したかったのですが、Lisp であることの重要な部分として Lisp が構文を定義していることを忘れていました。間違いなく Haskell は Lisp ではありませんが、後者は基本的に前者のプロセッサであるにもかかわらず、LiskellはLisp であるため、これはばかげていると思います。
Hoyte はいくつかの言語を比較し、Haskell は型が厳しすぎて学者向けでしかないため、Lisp ではないと主張していますが、Common Lisp はプロトタイピング言語に似ています (厳密さがなく、動的型付け)。
参照: Doug Hoyte 著 Let Over Lambda—Lisp の 50 年 (Common Lisp に関する高度な書籍、http://letoverlambda.com/ )
Haskell と Common Lisp (おそらくすべての Lisp) は、関数型プログラミング (FP) パラダイムに対して最適化されています。Haskell は純粋ですが、Common Lisp は純粋ではありません。FP という用語を「完全な関数型プログラミング」とも対比してください。
プログラミング言語のパラダイムを比較するこの図も見てください: http://www.info.ucl.ac.be/~pvr/paradigms.html