2010-m1s1-compilation/lisp/notes/notes.txt

93 lines
3.7 KiB
Plaintext

Types
=====
CLTL 2 et 2.15
Les types LISP sont organisés avec un héritage multiple.
Les objets ont des types, pas les variables.
Voici la hiérarchie des types (CLTL 2.15) :
le type t (type, pas symbole) est le super-type (comme Object en Java).
Tous lesobjets sont de type t.
le type nil (type, pas symbole) est le super-sous-type.
Aucun objet n'est de type nil.
Donc c'est un sous-type de tous les autres types.
Les types suivants sont disjoints (un objet ne peut pas être dans 2 de ces types à la fois) :
cons symbol array number character hash-table readtable package pathname stream random-state
De plus, un type créé par defstruct ou defclass est disjoint de chacun des types ci-dessus.
function est disjoint de cons symbol array number character.
Par contre function n'est pas disjoint de list :
;; Intersection non nulle
(functionp '(lambda (x) x)) => t
(listp '(lambda (x) x)) => t
;; function pas inclus dans list
(functionp #'car) => t
(listp #'car) => nil
;; list pas inclus dans function
(functionp '(1 2 3)) => nil
(listp '(1 2 3)) => t
Hiérarchie des nombres :
Number
|
Complex -------|-------- Real
|
float --------|-------rational
| |
| ratio ------|------ integer
| |
| fixnum -----|----- bignum
|
|-------------|-------------|-----------|
short-float single-float double-float long-float
A chaque niveau, les deux types sont disjoints (complex et real, float et rational, ...).
Exception : les différents sous-types de float ont des relations d'inclusion bizarres (voir CLTL).
De plus, fixnum et bignum forment une partition de integer (il n'y a pas d'autre sous-type à par nil).
null est le type contenant uniquement le symbole nil. C'est un sous-type de symbol.
null et cons forment une partition de list : (listp l) === (xor (consp l) (nullp l))
etc... (voir cltl et implementation/types.lisp).
Pour connaître le type de chaque objet, on utilise les n premiers bits,
plus les relations d'inclusion (voir implementation/types.lisp).
Par ex (tous les mots font 32 bits) :
1ers bits Passage par pointeur / valeur Description
===============================================================
0... P cons (les 31 bits restants sont l'adresse du car, puis 32 bits pour l'adresse du cdr).
Si tout est à 0 (64 bits tous à zéro), c'est nil
100... V fixnum (29 bits)
10100... V caractères unicode sur 8 bits ;; TODO : y a-t-il des caractères unicode dans le standard ?
10101... V caractères unicode sur 16 bit
110... P symbol
111... Tout le reste :
11100000... P array
11100001... P complex
11100010... P bignum
11100011... P ratio
111001xx... ? floats (xx : 00 = short, 01 = single, 10 = double, 11 = long)
11101000... P hash-table
11101001... P readtable
11101010... P package
11101011... P pathname
11101100... P stream
11101101... P random-state
11101110... P function (attention: d'autes objets peuvent être des fonctions)
Comme il n'y a très peu de valeurs qui pourraient être passées par valeur, je suggère qu'on passe tout par pointeur.
Les symboles
============
CLTL 2
Un symbole, (par ex 'foo), est un "objet" (commençant par 110 dans l'exemple ci-dessus).
Lorsqu'on écrit 'foo, c'est remplacé par un pointeur sur cet objet.
Les symboles ont une liste de propriétés (qu'on implémentera par une alist)
Les symboles ont un nom (qu'on implémentera par une chaîne de caractères).
Le symbole contiendra donc deux pointeurs vers son nom et sa liste de propriétés.
Le symbole nil existe toujours (et a l'adresse 0)