2012-06-28 10 views
8

Esiste una sinergia tra l'apprendimento di lingue Lisp diverse? Attualmente sto imparando Emacs Lisp, poiché è immediatamente utile nel mio uso quotidiano di Emacs, tuttavia sono affascinato da tutti i Lisps, quindi forse un giorno imparerò e userò altri. Imparare Emacs Lisp mi aiuterà, quando inizierò a scavare in Common Lisp, Scheme o Clojure? In altre parole, sarà per me come imparare una lingua completamente nuova, o alcune nozioni e paradigmi sono comuni? Sono anche interessato al confronto di differenze uniche tra i Lisps, che saranno un problema, quando vengo da un Lisp a un altro.L'apprendimento di un Lisp aiuta nell'apprendimento dell'altro?

Nel How to go about learning Common Lisp and Emacs Lisp? si dice che ci sarà "spreco", ma non viene elaborato, fino a che punto.

+4

* Implementare * il proprio Lisp sarebbe certamente di aiuto nell'apprendimento degli altri Lisps. –

risposta

15

- è molto più semplice trovare un nuovo Lisp se ne conosci già uno.

Motivi:

  • Capirete il concetto di "codice è dati" e metaprogrammazione in una lingua homoiconic (questo è senza dubbio il più grande singola cosa che rende unica Lisps/distintivo da altre lingue)
  • Potrai leggere la sintassi Lisp molto più facilmente. Ci vogliono alcune settimane per arrivare al punto in cui "vedi" la struttura del codice Lisp, ma dopo quel punto diventa molto più facile. Inizi a ignorare le parentesi dopo un po '.
  • Lo stile di sviluppo è simile, interagendo con un ambiente in esecuzione utilizzando un REPL
  • Essi condividono idiomi comuni, ad es. l'uso di liste e varie tecniche di programmazione funzionale
18

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 (!):

  1. Common Lisp
  2. Scheme
  3. Clojure
  4. 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.

+2

Hmm. L'unico problema che prendo con questo ordine di preferenza è che non sembra dare la priorità all'usabilità pratica immediata - un'area in cui Clojure brilla; è facile trovare opportunità pratiche per l'utilizzo di un linguaggio basato su JVM sul posto di lavoro (e mentre esistono alcune implementazioni di Schema basate su JVM, poche o nessuna hanno un'interoperabilità paragonabile) e l'ampiezza delle librerie disponibili per Clojure è di gran lunga migliore di quella disponibile per qualsiasi particolare implementazione del Programma (la frammentazione in quel mondo diventa piuttosto spiacevole quando si inizia a provare a fare un lavoro pratico). –

+6

Sì, non sono d'accordo con Rainer sul fatto che Common Lisp/Scheme sia il "più mainstream" Lisp. Non fraintendermi, io amo CL, ma Clojure è di gran lunga il più "vero mondo" Lisp in questi giorni. Confronta ad esempio la difficoltà di usare ASDF con la facilità di Leiningen/Clojars (e altrettanto semplice accesso a tutti i repository Java di Maven). Le pratiche di sviluppo CL sono un po 'arretrate, ad esempio tutti utilizzano il trunk più recente di ogni libreria. Le librerie Clojure tendono ad essere ben collaudate, versionate, su github/semplici da contribuire. Le librerie CL sono in genere progetti di lupo solitario, aggiornati alcuni anni fa – rplevy

+2

@CharlesDuffy: Non sono assolutamente d'accordo, Common Lisp è incentrato sull'usabilità. Se vuoi interagire con la JVM guarda [ABCL] (http://common-lisp.net/project/armedbear/), se vuoi interagire con C guarda [CFFI] (http: // common-lisp .net/progetto/CFFI /). E [Practical Common Lisp] (http://common-lisp.net/project/cffi/) è un ottimo tutorial. – Daimrod