Common Lisp Object System

Infos
Image:WikiLettreMini.png Cette page est considérée comme un article à approfondir. Le Common Lisp Object System, souvent abrégé en CLOS (prononcé 'si-lauss'), est l'ensemble des primitives présentes dans le langage de programmation Common Lisp pour construire un programme orienté objet. Il existe également une version de CLOS pour le langage Scheme, nommée TinyClos.
Common Lisp Object System

Image:WikiLettreMini.png Cette page est considérée comme un article à approfondir. Le Common Lisp Object System, souvent abrégé en CLOS (prononcé 'si-lauss'), est l'ensemble des primitives présentes dans le langage de programmation Common Lisp pour construire un programme orienté objet. Il existe également une version de CLOS pour le langage Scheme, nommée TinyClos.

Présentation

CLOS est un système objet à classes (il existe des systèmes à prototypes). Il descend de flavors et common loops, développés dans les années 1980. Common Lisp a été le premier langage à objet standardisé par l'ANSI, en 1995, précédant de peu SmallTalk.

Les objets et Lisp

D'un certain point de vue, Lisp est un langage orienté objet depuis le début : les structures de données manipulées ont une identité et sont réflexives. La seule chose qui lui manquait pour recevoir l'estampille orienté objet, est la capacité d'étendre le système de types de Lisp.

Caractéristiques


- héritage multiple
- sélection multiple
- combinaison de méthodes
- protocole à méta-objets (ou MOP)

Primitives

La plus petite définition de classe

(defclass foo ) ;; équivalent de (defclass foo (Object) ) Par défaut, une classe est un sous-type de Object. Les types par défaut de Common Lisp (nombres, chaînes, hashages, vecteurs, etc.) ne sont pas dérivables.

Créer une instance

(make-instance 'foo)

Attributs : définition, initialiseur, accesseurs, allocation

À partir d'un exemple plus intéressant, on montre les principales caractéristiques : (defclass graphe ((noeuds :accessor noeuds :initform (make-hash-table)) (arcs :accessor arcs :initform (make-hash-table))) (defclass noeud ((data :accessor data :initarg :data) (in-arcs :accessor in-arcs :initform (make-hash-table)) (out-arcs :accessor out-arcs :initform (make-hash-table))) (defclass arc ((in-noeud :accessor in-noeud :initarg :in-noeud) (out-noeud :accessor out-noeud :initarg :out-noeud))) Les attributs d'une classe sont nommés slots dans la terminologie de CLOS. Chaque slot est défini par une liste contenant au minimum son nom, en première position. Des accesseurs en lecture seule (:reader) ou lecture-écriture (:accessor ou la combinaison de :reader et :writer) peuvent être spécifiés, ainsi que la valeur initiale (:initform) et un nom pour donner une valeur au moment de l'instanciation. Ainsi, pour construire un nœud doté d'une boucle, on peut écrire : (defparameter
-un-noeud
- (make-instance 'noeud)) (defparameter
-un-arc
- (make-instance 'arc :in-noeud
-un-noeud
- :out-noeud
-un-noeud
-)) (setf (gethash (in-arcs
-un-noeud
-)
-un-arc
-)
-un-arc
-) (setf (gethash (out-arcs
-un-noeud
-)
-un-arc
-)
-un-arc
-) Ces manipulations de tables de hashage étant lourdes, on se construit un opérateur sethash pour en racourcir l'expression : (defmacro sethash (key value hash) `(setf (gethash , key , hash) , value)) Ainsi armé, on peut réécrire les deux lignes précédents : (sethash (in-arcs
-un-noeud
-)
-un-arc
-) (sethash (out-arcs
-un-noeud
-)
-un-arc
-)

Méthodes

Voici la plus grande originalité de CLOS : les méthodes n'y sont pas définies sur une classe. Au lieu de cela, elles sont définies un tuple de classes. Par exemple, on veut simplifier la connexion des nœuds et des arcs.

Sélection simple

Dans un langage à sélection simple, il faudrait attacher la méthode connecter à la classe nœud OU à la classe arrête, pour pouvoir écrire : un_arc.connecter (un_noeud, un_autre_noeud) Ou encore : un_noeud.connecter (un_arc, un_autre_noeud) Une méthode a un paramètre privilégié, son receveur (au sens de la réception d'un message). La notation pointée souligne ce privilège.

Sélection multiple

Avec la sélection multiple de la méthode sur le tuple des arguments obligatoires, on n'a plus besoin de choisir : (defgeneric connecter ((noeud noeud arc)) Une fonction générique est un sac de méthodes. On y place la première : (defmethod connecter ((noeud-1 noeud) (noeud-2 noeud) (un-arc arc)) (setf (in-noeud un-arc) noeud-1) (setf (out-noeud un-arc) noeud-2) (sethash out-arcs noeud-1 un-arc) (sethash in-arcs noeud-2 un-arc)) On peut maintenant écrire, pour construire la boucle : (connecter
-un-noeud
-
-un-noeud
-
-un-arc
-) (... à continuer ...) Catégorie:Langage orienté objet de:Common Lisp Object System en:Common Lisp Object System es:CLOS ja:Common Lisp Object System ru:CLOS
Sujets connexes
Années 1980   Common Lisp   Langage de programmation   Lisp   Protocole à méta-objets   Scheme  
#
Accident de Beaune   Amélie Mauresmo   Anisocytose   C3H6O   CA Paris   Carole Richert   Catherinettes   Chaleur massique   Championnat de Tunisie de football D2   Classement mondial des entreprises leader par secteur   Col du Bonhomme (Vosges)   De viris illustribus (Lhomond)   Dolcett   EGP  
^