Lisp の古い基礎を学びたい場合は、Emacs Lisp で十分です。
Emacs Lisp: Emacs で使用できます。開発環境が含まれています。主流の Lisp の古い方言。多くの概念が欠けています。エディタ プログラミング用の拡張機能が多数あります。Common Lisp と Emacs Lisp は、いくつかの直接的な遺産 (命名、概念など) を共有しています。
一般的な Lisp。学ぶべき良い本がたくさんあります。Lisp の多くの概念 (OO プログラミングを含む) は Common Lisp で学ぶことができます。強くお勧めします。Common Lisp には最も重要な Lisp 機能が組み込まれており、残りはライブラリが提供します。その周りで学べることはたくさんあります。
スキーム: 70 年代に作成された別の Lisp 方言。Emacs Lisp や Common Lisp とは直接互換性がありません。優れた本やその他のチュートリアル資料がたくさんあります。Lisp の基本といくつかのより高度なことを学習するために強くお勧めします。Scheme を深く掘り下げるほど、Emacs Lisp や Common Lisp とは異なって見えます。
Clojure: 非常に異なる Lisp 方言。Common Lisp、Emacs Lisp、Scheme とは互換性がありません。いくつかの概念を共有しますが、いくつかの概念は異なる働きをします。良い本。Lisp や特に Clojure を学びたい場合にお勧めします。Clojure は、関数型プログラミングと並行プログラミング (非常に関連性の高いトピック) に重点を置いています。
より主流の Lisp (典型的な Lisp 方言のルック アンド フィールを備えた Lisp) を学びたい場合は、Common Lisp または Scheme をお勧めします。
Lisp (!) を学習するための私の言語の好みは次のようになります。
- Common Lisp
- 図式
- クロージャ
- Emacs Lisp
例を挙げると:
これは、1960 年に書かれたMcCarthy's LispCOLLAPSE
の関数です ( Lisp I Programmer's manual、1960 年、101 ページから)。それは基本的に、多くの Lisp 演習での関数です。ネストされたリストを受け取り、単一のリストにアトムを含む新しいリストを返します。FLATTEN
DEFINE
(((COLLAPSE,(LAMBDA,(L),(COND,
((ATOM,L),(CONS,L,NIL))
((NULL,(CDR,L)),
(COND,((ATOM,(CAR,L)),L),(T,(COLLAPSE,(CAR,L)))))
(T,(APPEND,(COLLAPSE,(CAR,L)),(COLLAPSE,(CDR,L)))))
))))))
これはCommon Lispバージョンです。大文字のままにすることも、小文字に変換することもできます。どちらも機能します。
(DEFUN COLLAPSE (L)
(COND
((ATOM L) (CONS L NIL))
((NULL (CDR L))
(COND ((ATOM (CAR L)) L)
(T (COLLAPSE (CAR L)))))
(T (APPEND (COLLAPSE (CAR L))
(COLLAPSE (CDR L))))))
基本的に同じです。関数を定義するためのフォームのみ、名前と構文が異なります。それ以外の場合、コードは完全に同一です。
Common Lispで McCarthy の例を試してください:
CL-USER > (COLLAPSE '(((A B) ((C))) ((D (E F)) (G) ((H)))))
(A B C D E F G H)
走る。
では、GNU Emacs を使用してEmacs Lispで試してみましょう。Emacs Lisp には小文字の識別子があります。
ELISP> (defun collapse (l)
(cond
((atom l) (cons l nil))
((null (cdr l))
(cond ((atom (car l)) l)
(t (collapse (car l)))))
(t (append (collapse (car l))
(collapse (cdr l))))))
ELISP> (collapse '(((a b) ((c))) ((d (e f)) (g) ((h)))))
(a b c d e f g h)
変更なしでEmacs Lispで実行されます。
同様のバージョンをSchemeで入手できます(マイナーな名前変更):.
ここではプチシェスキームで:
> (define collapse
(lambda (l)
(cond
((atom? l) (cons l '()))
((null? (cdr l))
(cond ((atom? (car l)) l)
(else (collapse (car l)))))
(else (append (collapse (car l))
(collapse (cdr l)))))))
を使用DEFINE
して関数を定義できます。COND
少し違って見えます。()
空のリストです。述語には が?
追加されています。
> (collapse '(((a b) ((c))) ((d (e f)) (g) ((h)))))
(a b c d e f g h)
実行します。
Clojure では、見た目が異なります。基本的に、コードの多くを再考する必要があります。
これは Clojure 独自の の実装ですflatten
:
(defn flatten
[x]
(filter (complement sequential?)
(rest (tree-seq sequential? seq x))))
Lisp バージョンの精神でa を書くことができますflatten
- それでも見た目は異なります。
rosetta.orgから:
(defn flatten [coll]
(lazy-seq
(when-let [s (seq coll)]
(if (coll? (first s))
(concat (flatten (first s)) (flatten (rest s)))
(cons (first s) (flatten (rest s)))))))
名前が異なり、構文が異なり、セマンティクスが異なります (リストの代わりに遅延シーケンスで動作します)。
Common Lisp、Emacs Lisp、Visual Lisp、ISLISP などの方言は、伝統を守ろうとします。
Scheme や Clojure などの方言は、名前や構文に縛られていないと感じました。彼らはさまざまな方向に革新をもたらしました。スキームは、古い機能の直接バージョンを引き続き提供します。Clojure にはありません。Clojure プログラマーは、これを欠点とは見なしません。