1) Un nuovo concetto di variabili. In Lisp, tutte le variabili sono effettivamente puntatori. I valori sono quelli che hanno tipi, non variabili, e assegnare o associare variabili significa copiare i puntatori, non ciò a cui puntano.
(defun print-twice (it)
(print it)
(print it))
'it' è una variabile. Può essere associato a QUALSIASI valore. Non ci sono restrizioni e nessun tipo associato alla variabile. Se si chiama la funzione, non è necessario copiare l'argomento. La variabile è simile a un puntatore. Ha un modo per accedere al valore associato alla variabile. Non è necessario riservare memoria. Siamo in grado di passare qualsiasi oggetto dati quando chiamiamo la funzione: qualsiasi dimensione e qualsiasi tipo.
Gli oggetti dati hanno un 'tipo' e tutti gli oggetti dati possono essere interrogati per il suo 'tipo'.
(type-of "abc") -> STRING
2) Un tipo di simbolo. I simboli differiscono dalle stringhe in quanto è possibile verificare l'uguaglianza confrontando un puntatore.
Un simbolo è un oggetto dati con un nome. Di solito il nome può essere usato per trovare l'oggetto:
|This is a Symbol|
this-is-also-a-symbol
(find-symbol "SIN") -> SIN
Poiché i simboli sono oggetti dati reali, possiamo testare se sono lo stesso oggetto:
(eq 'sin 'cos) -> NIL
(eq 'sin 'sin) -> T
Questo ci consente ad esempio di scrivere una frase con simboli:
(defvar *sentence* '(mary called tom to tell him the price of the book))
Ora possiamo contare il numero di THE nella frase:
(count 'the *sentence*) -> 2
In Common Lisp i simboli non solo hanno un nome, ma possono anche avere un valore, una funzione, un elenco di proprietà e un pacchetto. Quindi i simboli possono essere usati per nominare variabili o funzioni. L'elenco delle proprietà viene generalmente utilizzato per aggiungere metadati ai simboli.
3) Una notazione per il codice usando alberi di simboli.
Lisp utilizza le sue strutture di dati di base per rappresentare il codice.
L'elenco (* 3 2) può essere sia dati che codice:
(eval '(* 3 (+ 2 5))) -> 21
(length '(* 3 (+ 2 5))) -> 3
L'albero:
CL-USER 8 > (sdraw '(* 3 (+ 2 5)))
[*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
* 3 [*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
+ 2 5
4) L'intera lingua è sempre disponibile. Non esiste una reale distinzione tra tempo di lettura, tempo di compilazione e runtime. È possibile compilare o eseguire il codice durante la lettura, leggere o eseguire il codice durante la compilazione e leggere o compilare il codice in fase di esecuzione.
Lisp fornisce le funzioni READ per leggere dati e codice dal testo, LOAD per caricare il codice, EVAL per valutare il codice, COMPILE per compilare il codice e PRINT per scrivere dati e codice nel testo.
Queste funzioni sono sempre disponibili. Non vanno via. Possono far parte di qualsiasi programma. Ciò significa che qualsiasi programma può leggere, caricare, valutare o stampare il codice - sempre.
In che modo differiscono in lingue come C o Java?
Tali lingue non forniscono simboli, codice come dati o valutazione di runtime dei dati come codice. Gli oggetti dati in C sono in genere non tipizzati.
Altre lingue diverse dalle lingue della famiglia LISP hanno uno di questi costrutti ora?
Molte lingue hanno alcune di queste capacità.
La differenza:
In Lisp queste funzionalità sono progettate nella lingua in modo che siano facili da usare.