1) Un nouveau concept de variables. En Lisp, toutes les variables sont en fait des pointeurs. Les valeurs sont ce qui a des types, pas des variables, et l'affectation ou la liaison de variables signifie copier des pointeurs, pas ce qu'ils pointent.
(defun print-twice (it)
(print it)
(print it))
«c'est» est une variable. Il peut être lié à N'IMPORTE QUELLE valeur. Il n'y a aucune restriction et aucun type associé à la variable. Si vous appelez la fonction, l'argument n'a pas besoin d'être copié. La variable est similaire à un pointeur. Il a un moyen d'accéder à la valeur qui est liée à la variable. Il n'est pas nécessaire de réserver de la mémoire. Nous pouvons passer n'importe quel objet de données lorsque nous appelons la fonction: n'importe quelle taille et n'importe quel type.
Les objets de données ont un «type» et tous les objets de données peuvent être interrogés pour son «type».
(type-of "abc") -> STRING
2) Un type de symbole. Les symboles diffèrent des chaînes en ce que vous pouvez tester l'égalité en comparant un pointeur.
Un symbole est un objet de données avec un nom. Habituellement, le nom peut être utilisé pour trouver l'objet:
|This is a Symbol|
this-is-also-a-symbol
(find-symbol "SIN") -> SIN
Puisque les symboles sont de vrais objets de données, nous pouvons tester s'ils sont le même objet:
(eq 'sin 'cos) -> NIL
(eq 'sin 'sin) -> T
Cela nous permet par exemple d'écrire une phrase avec des symboles:
(defvar *sentence* '(mary called tom to tell him the price of the book))
Maintenant, nous pouvons compter le nombre de THE dans la phrase:
(count 'the *sentence*) -> 2
En Common Lisp, les symboles ont non seulement un nom, mais ils peuvent également avoir une valeur, une fonction, une liste de propriétés et un package. Ainsi, les symboles peuvent être utilisés pour nommer des variables ou des fonctions. La liste des propriétés est généralement utilisée pour ajouter des méta-données aux symboles.
3) Une notation pour le code utilisant des arbres de symboles.
Lisp utilise ses structures de données de base pour représenter le code.
La liste (* 3 2) peut être à la fois des données et du code:
(eval '(* 3 (+ 2 5))) -> 21
(length '(* 3 (+ 2 5))) -> 3
L'arbre:
CL-USER 8 > (sdraw '(* 3 (+ 2 5)))
[*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
* 3 [*|*]--->[*|*]--->[*|*]--->NIL
| | |
v v v
+ 2 5
4) Toute la langue toujours disponible. Il n'y a pas de réelle distinction entre le temps de lecture, le temps de compilation et le temps d'exécution. Vous pouvez compiler ou exécuter du code lors de la lecture, lire ou exécuter du code lors de la compilation, et lire ou compiler du code au moment de l'exécution.
Lisp fournit les fonctions READ pour lire des données et du code à partir de texte, LOAD pour charger du code, EVAL pour évaluer le code, COMPILE pour compiler du code et PRINT pour écrire des données et du code dans du texte.
Ces fonctions sont toujours disponibles. Ils ne s'en vont pas. Ils peuvent faire partie de n'importe quel programme. Cela signifie que n'importe quel programme peut lire, charger, évaluer ou imprimer du code - toujours.
En quoi sont-ils différents dans des langages comme C ou Java?
Ces langages ne fournissent pas de symboles, de code sous forme de données ou d'évaluation d'exécution des données sous forme de code. Les objets de données en C ne sont généralement pas typés.
Est-ce que d'autres langues autres que les langues de la famille LISP ont l'une de ces constructions maintenant?
De nombreuses langues ont certaines de ces capacités.
La différence:
En Lisp, ces capacités sont conçues dans le langage afin d'être faciles à utiliser.