Se si desidera imparare alcune nozioni di base precedenti di Lisp, allora Emacs Lisp va bene.
Emacs Lisp: può essere utilizzato in Emacs. Ambiente di sviluppo incluso. Vecchio dialetto del mainstream Lisp. Manca un sacco di concetti. Ha molte estensioni per la programmazione dell'editor. Common Lisp ed Emacs Lisp condividono alcune eredità dirette (denominazione, concetti, ...).
Comune Lisp. Un sacco di buoni libri da cui imparare. Un sacco di concetti Lisp (compresa la programmazione OO) possono essere appresi con Common Lisp. Altamente raccomandato. Common Lisp ha le più importanti strutture Lisp integrate e le librerie forniscono il resto. C'è una grande quantità di cose che possono essere apprese attorno ad esso.
Schema: diverso dialetto Lisp creato negli anni '70. Non è direttamente compatibile con Emacs Lisp o Common Lisp. Un sacco di libri eccellenti e altro materiale didattico. Altamente raccomandato per l'apprendimento delle basi Lisp e alcune cose più avanzate. Più si scava in Scheme più appare diverso da Emacs Lisp o anche Common Lisp.
Clojure: dialetto Lisp molto diverso. Non compatibile con Common Lisp, Emacs Lisp o Scheme. Condivide alcuni concetti, alcuni concetti funzionano in modo diverso. Buoni libri. Consigliato se vuoi imparare qualche Lisp o Clojure. Clojure pone l'accento sulla programmazione funzionale e concorrente - argomenti molto rilevanti.
Se volete saperne di più mainstream Lisp (un Lisp che con un look and feel di un tipico dialetto Lisp), mi sento di raccomandare Common Lisp o Scheme.
La mia lingua preferita per l'apprendimento Lisp sarebbe (!):
- Common Lisp
- Scheme
- Clojure
- Emacs Lisp
Per fare un esempio:
Questa è la funzione COLLAPSE
da Lisp di McCarthy, scritta nel 1960 (dallo Lisp I Programmer's manual, 1960, pagina 101). È fondamentalmente quello che in molti esercizi Lisp è la funzione FLATTEN
. Prende una lista annidata e restituisce una nuova lista con gli atomi in una singola lista.
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)))))
))))))
Questa è la versioneCommon Lisp. Puoi tenerlo in maiuscolo o convertirlo in minuscolo. Entrambe le opere.
(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))))))
È praticamente lo stesso. Solo il modulo per la definizione delle funzioni ha un nome e una sintassi diversi. Altrimenti il codice è completamente identico.
Prova esempio di McCarthy nel Common Lisp:
CL-USER > (COLLAPSE '(((A B) ((C))) ((D (E F)) (G) ((H)))))
(A B C D E F G H)
Si corre.
Ora proviamo in Emacs Lisp, utilizzando GNU Emacs. Emacs Lisp ha identificatori minuscole:
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)
viene eseguito in Emacs Lisp senza cambiamenti.
È possibile ottenere versioni simili che vanno in Schema (ridenominazioni minori) :.
Qui in Petite Chez 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)))))))
Possiamo usare DEFINE
per definire una funzione. COND
sembra leggermente diverso. ()
è la lista vuota. I predicati hanno un ?
aggiunto.
> (collapse '(((a b) ((c))) ((d (e f)) (g) ((h)))))
(a b c d e f g h)
Corse.
In Clojure sarebbe diverso. Fondamentalmente devi ripensare a gran parte del codice.
Si tratta di una propria implementazione di Clojure di flatten
:
(defn flatten
[x]
(filter (complement sequential?)
(rest (tree-seq sequential? seq x))))
È possibile scrivere un flatten
nello spirito della versione Lisp - sarebbe comunque un aspetto diverso.
Da 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)))))))
nomi sono diversi, la sintassi è diversa, la semantica è diversa (lavora su sequenze pigri, invece di liste).
Dialetti come Common Lisp, Emacs Lisp, Visual Lisp, ISLISP e altri cercano di mantenere il patrimonio.
Dialetti come Schema o Clojure non si sentivano legati ai nomi e alla sintassi. Hanno innovato in varie direzioni. Scheme fornisce ancora versioni dirette della vecchia funzionalità. Clojure no. I programmatori Clojure non vedranno questo come uno svantaggio.
* Implementare * il proprio Lisp sarebbe certamente di aiuto nell'apprendimento degli altri Lisps. –