Ricerca…


Osservazioni

Questa è una semplice funzione di ciao mondo in Common Lisp. Gli esempi stamperanno il testo Hello, World! (senza virgolette, seguito da una nuova riga) per l'output standard.

Common Lisp è un linguaggio di programmazione che è ampiamente utilizzato in modo interattivo utilizzando un'interfaccia nota come REPL. Il REPL (Read Eval Print Loop) consente di digitare il codice, farlo valutare (eseguire) e vedere immediatamente i risultati. Il prompt per REPL (al punto in cui si digita il codice da eseguire) è indicato da CL-USER> . A volte qualcosa di diverso da CL-USER apparirà prima del > ma questo è ancora un REPL.

Dopo il prompt viene fornito un codice, di solito una singola parola (cioè un nome di variabile) o un modulo (un elenco di parole / moduli racchiusi tra ( e ) ) (cioè una chiamata di funzione o una dichiarazione, ecc.). Nella riga successiva sarà presente qualsiasi output che il programma stampa (o nulla se il programma non stampa nulla) e quindi i valori restituiti valutando l'espressione. Normalmente un'espressione restituisce un valore ma se restituisce più valori compaiono una volta per riga.

Versioni

Versione Data di rilascio
Lisp comune 1984-01-01
ANSI Common Lisp 1994-01-01

Ciao mondo

Quello che segue è un estratto da una sessione REPL con Common Lisp in cui un "Hello, World!" la funzione è definita ed eseguita. Vedere le note in fondo a questa pagina per una descrizione più approfondita di un REPL.

CL-USER> (defun hello ()
           (format t "Hello, World!~%"))
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> 

Questo definisce la "funzione" di zero argomenti denominata hello , che scriverà la stringa "Hello, World!" seguito da una nuova riga sullo standard output e restituire NIL .

Per definire una funzione scriviamo

(defun name (parameters...)
  code...)

In questo caso la funzione è chiamata hello , non richiede parametri e il codice che esegue è quello di effettuare una chiamata di funzione. Il valore restituito da una funzione lisp è l'ultimo bit di codice nella funzione da eseguire in modo che i ritorni di hello qualsiasi (format t "Hello, World!~%") Restituiscano.

In lisp per chiamare una funzione si scrivono (function-name arguments...) dove function-name è il nome della funzione e arguments... è l'elenco degli argomenti (separati da spazi) della chiamata. Ci sono alcuni casi speciali che assomigliano a chiamate di funzioni ma, ad esempio, nel codice precedente non c'è alcuna funzione di defun che viene chiamata, viene trattata in modo speciale e definisce una funzione.

Al secondo prompt del REPL, dopo aver definito la funzione hello , la chiamiamo senza parametri scrivendo (hello) . Questo a sua volta chiamerà il format funzione con i parametri t e "Hello, World!~%" . La funzione format produce output formattati in base agli argomenti che vengono forniti (un po 'come una versione avanzata di printf in C). Il primo argomento dice che dove output, con t che significa standard output. Il secondo argomento indica cosa stampare (e come interpretare eventuali parametri aggiuntivi). La direttiva (codice speciale nel secondo argomento) ~% indica al formato di stampare una nuova riga (ovvero su UNIX potrebbe scrivere \n e su windows \r\n ). Il formato di solito restituisce NIL (un po 'come NULL in altre lingue).

Dopo il secondo prompt vediamo che Hello, World è stato stampato e nella riga successiva che il valore restituito era NIL .

Ciao, nome

Questo è un esempio un po 'più avanzato che mostra alcune altre funzionalità di Common Lisp. Iniziamo con un semplice Hello, World! funzione e dimostrare alcuni sviluppi interattivi al REPL. Si noti che qualsiasi testo da un punto e virgola ; , per il resto della linea è un commento.

CL-USER> (defun hello ()
       (format t "Hello, World!~%")) ;We start as before
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> (defun hello-name (name) ;A function to say hello to anyone
       (format t "Hello, ~a~%" name)) ;~a prints the next argument to format
HELLO-NAME
CL-USER> (hello-name "Jack")
Hello, Jack
NIL
CL-USER> (hello-name "jack") ;doesn't capitalise names
Hello, jack
NIL
CL-USER> (defun hello-name (name) ;format has a feature to convert to title case
       (format t "Hello, ~:(~a~)~%" name)) ;anything between ~:( and ~) gets it
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello-name "jack")
Hello, Jack
NIL
CL-USER> (defun hello-name (name)
       (format t "Hello, ~:(~a~)!~%" name))
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello-name "jack") ;now this works
Hello, Jack!
NIL
CL-USER> (defun hello (&optional (name "world")) ;we can take an optional argument
       (hello-name name)) ;name defaults to "world"
WARNING: redefining COMMON-LISP-USER::HELLO in DEFUN
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> (hello "jack")
Hello, Jack!
NIL
CL-USER> (hello "john doe") ;note that this capitalises both names
Hello, John Doe!
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~a ~r" name number)) ;~r prints a number in English
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16) ;this doesn't quite work
Hello, Louis sixteen
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~:(~a ~:r~)!" name number)) ;~:r prints an ordinal
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16)
Hello, Louis Sixteenth!
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~:(~a ~@r~)!" name number)) ;~@r prints Roman numerals
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16)
Hello, Louis Xvi!
NIL
CL-USER> (defun hello-person (name &key (number)) ;capitalisation was wrong
       (format t "Hello, ~:(~a~) ~:@r!" name number))
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16) ;thats better
Hello, Louis XVI!
NIL
CL-USER> (hello-person "Louis") ;we get an error because NIL is not a number
Hello, Louis ; Evaluation aborted on #<SB-FORMAT:FORMAT-ERROR {1006641AB3}>.
CL-USER> (defun say-person (name &key (number 1 number-p)
                                      (title nil) (roman-number t))
       (let ((number (if number-p
                 (typecase number
                   (integer
                (format nil (if roman-number " ~:@r" " ~:(~:r~)") number))
                   (otherwise
                (format nil " ~:(~a~)" number)))
                 "")) ; here we define a variable called number
         (title (if title 
                (format nil "~:(~a~) " title)
                ""))) ; and here one called title
         (format nil "~a~:(~a~)~a" title name number))) ;we use them here

SAY-PERSON
CL-USER> (say-person "John") ;some examples
"John"
CL-USER> (say-person "john doe")
"John Doe"
CL-USER> (say-person "john doe" :number "JR")
"John Doe Jr"
CL-USER> (say-person "john doe" :number "Junior")
"John Doe Junior"
CL-USER> (say-person "john doe" :number 1)
"John Doe I"
CL-USER> (say-person "john doe" :number 1 :roman-number nil) ;this is wrong
"John Doe First"
CL-USER> (defun say-person (name &key (number 1 number-p)
                                      (title nil) (roman-number t))
       (let ((number (if number-p
                 (typecase number
                   (integer
                (format nil (if roman-number " ~:@r" " the ~:(~:r~)") number))
                   (otherwise
                (format nil " ~:(~a~)" number)))
                 ""))
         (title (if title 
                (format nil "~:(~a~) " title)
                "")))
         (format nil "~a~:(~a~)~a" title name number)))
WARNING: redefining COMMON-LISP-USER::SAY-PERSON in DEFUN
SAY-PERSON
CL-USER> (say-person "john doe" :number 1 :roman-number nil) ;thats better
"John Doe the First"
CL-USER> (say-person "louis" :title "king" :number 16 :roman-number nil)
"King Louis the Sixteenth"
CL-USER> (say-person "louis" :title "king" :number 16 :roman-number t)
"King Louis XVI"
CL-USER> (defun hello (&optional (name "World") &rest arguments) ;now we will just
       (apply #'hello-name name arguments)) ;pass all arguments to hello-name
WARNING: redefining COMMON-LISP-USER::HELLO in DEFUN
HELLO
CL-USER> (defun hello-name (name &rest arguments) ;which will now just use
       (format t "Hello, ~a!" (apply #'say-person name arguments))) ;say-person
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello "louis" :title "king" :number 16) ;this works now
Hello, King Louis XVI!
NIL
CL-USER>

Questo evidenzia alcune delle funzioni avanzate della funzione di format del Common Lisp e alcune funzioni come parametri opzionali e argomenti di parole chiave (es . :number ). Questo dà anche un esempio di sviluppo interattivo a un REPL in comune lisp.

Il semplice programma Hello World in REPL

Common Lisp REPL è un ambiente interattivo. Ogni modulo scritto dopo il prompt viene valutato e il suo valore viene stampato in seguito come risultato della valutazione. Quindi il programma "Hello, World!" Più semplice possibile in Common Lisp è:

CL-USER> "Hello, World!"
"Hello, World!"
CL-USER>

Quello che succede qui è che una stringa costante viene data in input al REPL, viene valutata e il risultato viene stampato. Ciò che si può vedere da questo esempio è che le stringhe, come i numeri, i simboli speciali come NIL e T e alcuni altri letterali, sono forme di auto-valutazione : cioè valutano se stessi.

Espressioni di base

Proviamo alcune espressioni di base nella REPL:

CL-USER> (+ 1 2 3)
6
CL-USER> (- 3 1 1)
1
CL-USER> (- 3)
-3
CL-USER> (+ 5.3 (- 3 2) (* 2 2))
10.3
CL-USER> (concatenate 'string "Hello, " "World!")
"Hello, World!"
CL-USER> 

Il modulo base di un programma Common Lisp è la forma . In questi esempi abbiamo forme di funzioni , cioè espressioni, scritte come lista, in cui il primo elemento è un operatore (o funzione) e il resto degli elementi sono gli operandi (questo è chiamato "Notazione prefisso" o "Notazione polacca" “). La scrittura di moduli nel REPL causa la loro valutazione. Negli esempi è possibile visualizzare espressioni semplici i cui argomenti sono numeri, stringhe e simboli costanti (nel caso di 'string , che è il nome di un tipo). Puoi anche vedere che gli operatori aritmetici possono prendere qualsiasi numero di argomenti.

È importante notare che le parentesi sono parte integrante della sintassi e non possono essere utilizzate liberamente come in altri linguaggi di programmazione. Ad esempio il seguente è un errore:

(+ 5 ((+ 2 4)))
> Error: Car of ((+ 2 4)) is not a function name or lambda-expression. ...

Nelle forme comuni di Lisp possono essere anche dati, simboli, forme macro, forme speciali e forme lambda. Possono essere scritti per essere valutati, restituendo zero, uno o più valori, oppure possono essere dati in input a una macro, che li trasforma in altre forme.

Somma dell'elenco di numeri interi

(defun sum-list-integers (list)
    (reduce '+ list))

; 10
(sum-list-integers '(1 2 3 4))

; 55
(sum-list-integers '(1 2 3 4 5 6 7 8 9 10))

Espressioni lambda e funzioni anonime

Una funzione anonima può essere definita senza un nome attraverso un'espressione Lambda . Per definire questo tipo di funzioni, viene utilizzata la parola chiave lambda posto della parola chiave defun . Le seguenti righe sono tutte equivalenti e definiscono funzioni anonime che generano la somma di due numeri:

(lambda (x y) (+ x y))
(function (lambda (x y) (+ x y)))
#'(lambda (x y) (+ x y))

La loro utilità è evidente quando si creano forme Lambda , cioè una forma che è una lista in cui il primo elemento è l'espressione lambda e gli elementi rimanenti sono gli argomenti della funzione anonima. Esempi ( esecuzione online ):

(print ((lambda (x y) (+ x y)) 1 2)) ; >> 3

(print (mapcar (lambda (x y) (+ x y)) '(1 2 3) '(2 -5 0))) ; >> (3 -3 3)

Risorse di apprendimento Lisp comuni

Libri online

Questi sono libri che sono liberamente accessibili online.

Riferimenti online

  • Common Lisp Hyperspec è il documento di riferimento della lingua per Common Lisp.
  • The Common Lisp Cookbook è un elenco di utili ricette Lisp. Contiene anche un elenco di altre fonti online di informazioni CL.
  • Riferimento rapido Lisp comune ha fogli di riferimento Lisp stampabili.
  • Lispdoc.com ricerca diverse fonti di informazioni Lisp (Practical Common Lisp, Success Lisp, On Lisp, HyperSpec) per la documentazione.
  • L1sp.org è un servizio di reindirizzamento per la documentazione.

Libri offline

Questi sono libri che probabilmente dovrai acquistare o prestare da una biblioteca.

Comunità online

biblioteche

  • Quicklisp è un gestore di libreria per Common Lisp e ha una lunga lista di librerie supportate .
  • Quickdocs ospita la documentazione della libreria per molte librerie CL.
  • Awesome CL è un elenco di librerie, framework e altre cose lucide guidate dalla comunità, ordinate per categoria.

Ambienti Lisp preconfezionati

Si tratta di ambienti di editing Lisp facili da installare e da utilizzare poiché tutto ciò di cui si ha bisogno è preconfigurato e preconfigurato.

  • Portacle è un ambiente Lisp comune portatile e multipiattaforma. Viene fornito un Emacs leggermente personalizzato con Slime, SBCL (un'implementazione Common Common Lisp), Quicklisp e Git. Nessuna installazione necessaria, quindi è un modo molto semplice e veloce per iniziare.
  • Lispbox è un IDE (Emacs + SLIME), un ambiente Common Lisp (Clozure Common Lisp) e un gestore di libreria (Quicklisp), pre-confezionato come archivi per Windows, Mac OSX e Linux. Discendente di "Lisp in a Box" Consigliato nel libro Practical Common Lisp.
  • Non pre-confezionato, ma SLIME trasforma Emacs in un IDE Lisp comune e ha un manuale utente per aiutarti a iniziare. Richiede un'implementazione Common Lisp separata.

Implementazioni comuni di Lisp

Questa sezione elenca alcune implementazioni CL comuni e i relativi manuali. Salvo diversa indicazione, si tratta di implementazioni di software libero. Vedi anche l' elenco di Cliki delle implementazioni comuni di Lisp del software libero e l'elenco di Wikipedia delle implementazioni comuni di Lisp comuni .



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow