1 Mercredi 3 Octobre 1984 INRIA Domaine de Voluceau Rocquencourt 78153 Le Chesnay Cedex Programmer en Ceyx Ceyx - Version 15 Jean-Marie Hullot Ete' 1984 Re'sume': ←C←e←y←x ←e←s←t ←u←n ←e←n←s←e←m←b←l←e ←d'←o←u←t←i←l←s ←p←e←r←m←e←t←t←a←n←t ←d←e ←f←a←c←i←l←i←t←e←r ←l←a ←t←a↑←c←h←e ←d←e←s ←p←r←o←g←r←a←m←m←e←u←r←s ←L←i←s←p ←p←o←u←r ←d←e'←f←i←n←i←r ←e←t ←m←a←n←i←p←u←l←e←r ←d←e←s ←s←t←r←u←c←t←u←r←e←s ←a←r←b←i←t←r←a←i←r←e←s. ←A←u←x ←s←t←r←u←c←t←u←r←e←s ←d←e'←f←i←n←i←e←s ←e←n ←C←e←y←x ←s←o←n←t ←a←s←s←o←c←i←e'←e←s ←d←e←s ←e←s←p←a←c←e←s ←s←e'←m←a←n←t←i←q←u←e←s, ←o←r←g←a←n←i←s←e'←s ←h←i←e'←r←a←r←c←h←i←q←u←e←m←e←n←t, ←d←a←n←s ←l←e←s←q←u←e←l←s ←s←o←n←t ←r←a←n←g←e'←e←s ←l←e←s ←f←o←n←c←t←i←o←n←s ←d←e ←m←a←n←i←p←u←l←a←t←i←o←n ←p←r←o←p←r←e←s ←a` ←c←e←s ←s←t←r←u←c←t←u←r←e←s. ←U←n ←s←t←y←l←e ←d←e ←p←r←o←g←r←a←m←m←a←t←i←o←n ←o←r←i←e←n←t←e'←e ←o←b←j←e←t←s ←a` ←l←a ←S←m←a←l←l←T←a←l←k ←e←s←t ←a←i←n←s←i ←r←e←n←d←u ←p←o←s←s←i←b←l←e. ←C←e←y←x ←e←s←t ←i←m←p←l←e'←m←e←n←t←e' ←e←n ←L←e←←L←i←s←p ←e←t ←f←o←n←c←t←i←o←n←n←e ←d←o←n←c ←s←u←r ←l←e←s ←n←o←m←b←r←e←u←s←e←s ←m←a←c←h←i←n←e←s ←o←u` ←c←e ←s←y←s←t←e`←m←e ←e←s←t ←i←m←p←l←a←n←t←e'. ←N←o←n ←c←o←m←p←i←l←e' ←i←l ←o←c←c←u←p←e ←3←0←0←0 ←c←e←l←l←u←l←e←s ←c←o←n←s ←d←a←n←s ←s←a ←v←e←r←s←i←o←n ←m←i←n←i←m←a←l←e ←e←t ←8←0←0←0 ←d←a←n←s ←s←a ←v←e←r←s←i←o←n ←c←o←m←p←l←e`←t←e ←a←v←e←c ←l←a ←b←i←l←i←o←t←h←e`←q←u←e ←i←n←i←t←i←a←l←e ←e←t ←l←e ←p←r←e'←c←o←m←p←i←l←a←t←e←u←r. 2 Mercredi 3 Octobre 1984 ←C←e ←d←o←c←u←m←e←n←t ←e←s←t ←l←e ←m←a←n←u←e←l ←p←r←o←g←r←a←m←m←e←u←r ←C←e←y←x. ←T←o←u←t←e←s ←l←e←s ←f←o←n←c←t←i←o←n←s ←d←u ←s←y←t←e`←m←e ←y ←s←o←n←t ←d←o←c←u←m←e←n←t←e'←e←s ←e←t ←d←e ←n←o←m←b←r←e←u←x ←p←r←o←g←r←a←m←m←e←s ←s←o←n←t ←p←r←e'←s←e←n←t←e'←s ←e←n ←a←n←n←e←x←e. Mots Clefs: ←L←i←s←p, ←L←e←←L←i←s←p. 3 Mercredi 3 Octobre 1984 4 Mercredi 3 Octobre 1984 ←V←o←u←l←o←i←r ←t←e←n←i←r ←u←n←e ←c←o←u←p←e ←e←t ←l'←e←m←p←l←i←r ←p←l←u←s ←q←u'←a` ←r←a←s ←b←o←r←d, ←c'←e←s←t ←p←e←i←n←e ←p←e←r←d←u←e. ←V←o←u←l←o←i←r ←m←a←n←i←e←r ←u←n ←o←u←t←i←l ←e←t ←s←a←n←s ←c←e←s←s←e ←l'←a←f←f←i←l←e←r, ←c←e←l←a ←n←e ←s←a←u←r←a←i←t ←d←u←r←e←r ←l←o←n←g←t←e←m←p←s. Lao Tseu 5 Mercredi 3 Octobre 1984 6 Mercredi 3 Octobre 1984 Avertissement Ce document constitue le manuel programmeur Ceyx. Si vous e↑tes de'butant en Ceyx, consultez d'abord le manuel d'initiation a` Ceyx, disponible comme rapport INRIA: o+ ←C←e←y←x: ←U←n←e ←I←n←i←t←i←a←t←i←o←n, (J.-M. Hullot). Programmer en Ceyx, c'est d'abord programmer en Lisp. Ceyx est e'crit en Le←Lisp, il serait donc bon aussi que vous ayez sous la main le manuel Le←Lisp, e'galement disponible comme rapport INRIA: o+ ←L←e←←L←i←s←p ←d←e ←l'←I←N←R←I←A, ←L←e ←M←a←n←u←e←l ←d←e ←R←e'←f←e'←r←e←n←c←e, (J. Chailloux). Enfin, vous trouverez dans les rapports suivants la documentation de processeurs spe'cialise's Ceyx: o+ ←V←p←r←i←n←t, ←L←e ←C←o←m←p←o←s←e←u←r ←C←e←y←x, (G. Berry, J.-M. Hullot), o+ ←C←X←Y←A←C←C ←e←t ←L←E←X-←K←I←T, (G. Berry, B.Serlet). 7 Mercredi 3 Octobre 1984 8 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les C H A P I T R E 1 Les Mode`les ←J←e←a←n-←M←a←r←i←e ←H←u←l←l←o←t 1.1 Introduction Les structures de donne'es fournies par une incarnation du langage Lisp telle que Le←Lisp peuvent e↑tre groupe'es en deux familles: o+ les structures atomiques: symbol, fix, float, string; o+ les structures composites: cons, vector. Le but premier de Ceyx est de: o+ cre'er de nouvelles structures de donne'es par composition de ces structures primitives, et de leur associer un nom; o+ de'finir automatiquement des fonctions Lisp de cre'ation d'instances de ces structures, o+ de'finir automatiquement des fonctions d'acce`s en lecture et en e'criture aux composantes des instances. Associer a` un nom struct une de'finition de mode`le consiste essentiellement a` associer a` ce nom un ←m←o←d←e`←l←e ←d←e ←s←t←r←u←c←t←u←r←e, c'est a` dire une information telle que: (defmodel struct (Cons symbol (Vector fix fix cons))) 9 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les pour dire que toutes les instances de ce mode`le sont une cellule cons dont le car est un symbole, le cdr un vecteur de longueur 3 dont la premie`re composante est un petit entier (fixnum), la seconde un petit entier, et la troisie`me une cellule cons. Le proble`me qui apparait rapidement losqu'on utilise ainsi des structures de donne'es ba↑ties a` partir de structures primitives est un proble`me d'acce`s aux diffe'rentes composantes des instances de ces structures. Au fur et a` mesure que la complexite' des structures croi↑t, la longueur des chai↑nes d'acce`s en car/cdr/vref croi↑t et la lisibilite' de'croi↑t. Pour re'soudre ce proble`me Ceyx donne la possibilite' de nommer les composantes auquelles on de'sire acce'der lors de la de'finition du mode`le: (defmodel struct (Cons (Field nom symbol) (Vector (Field x fix) (Field y fix) (Field obj cons)))) Une fonction Lisp de nom 'mkstruct' a` 3 arguments x, y et obj permettant d'engendrer des instances du mode`le struct dont les champs x y et obj ont des valeurs donne'es est de'finie par: (defmake struct mkstruct (x y obj)) Les fonctions d'acce`s en lecture/e'criture aux diverses composantes des instances sont de'finies par (defaccess struct) Ces fonctions portent les noms des divers champs du mode`le mais sont interne'es dans l'espace de noms (package) associe' au symbole struct #:struct:nom #:struct:x 10 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les #:struct:y #:struct:obj Ces fonctions prennent toutes un ou deux arguments; dans le cas d'un seul argument elles permettent de consulter la valeur du champ voulu de l'objet passe' en argument; dans le cas de deux elles permettent de remplacer la valeur stocke'e dans le champ voulu de l'objet premier argument par la valeur passe'e en deuxie`me argument. Exemples ? (setq x (mkstruct 1 2 '(a . b))) = (() . #[1 2 (a . b)]) ? (#:struct:nom x 'toto) = (toto . #[1 2 (a . b)]) ? (#:struct:nom x) = toto ? (#:struct:x x) = 1 ? (#:struct:y x) = 2 1.2 Le Langage de Description de Mode`les 1.2.1 Syntaxe Nous dirons qu'un symbole <symbol> ←a ←u←n←e ←v←a←l←e←u←r ←d←e ←m←o←d←e`←l←e si et seulement si <symbol> a e'te' de'clare' par: (defmodel <symbol> <model>) Nous appelons ←m←o←d←e`←l←e toute s-sexpression de la forme: <model> = <modelname> |<field> 11 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les |(Predicate <symbol> <sexpr>) |(List <model>) |(Cons <model>1 <model>2) |(Vector <model>1 ... <model>n) |<modelx> <modelname> = <symbol> ayant une valeur de mode`le <field> = (Field <symbol> <model> <sexpr>) |(Field <symbol> <model>) |(Field <symbol>) ou` <modelx> de'signe les macromode`les qui seront de'finis plus loin et <sexpr> les s-expressions Lisp de'finies par: <sexpr> = (<sexpr>1 . <sexpr>2) |#[<sexpr>1 ... <sexpr>n] |<symbol> |<string> |<fix> |<float> Exemples ? (defmodel symbol (Predicate symbolp 'nil)) = symbol ? (defmodel cons (Cons (Field car) (Field cdr))) = cons ? (defmodel number (Predicate numberp 0)) = number ? (defmodel lnumber (List number)) = lnumber ? (defmodel point (Cons (Field x number 0) (Field y number 0))) = point ? (defmodel segment (Vector (Field org (Cons (Field xorg number 0) (Field yorg number 0))) (Field ext (Cons (Field xext number 0) (Field yext number 0)))) 12 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les = segment 1.2.2 Se'mantique 1.2.2.1 Discrimination Les mode`les sont d'abord des ←s←c←h←e'←m←a←s ←d←e ←f←i←l←t←r←a←g←e de <sexpr>. Ainsi nous dirons que le mode`le (Predicate symbolp ()) ←f←i←l←t←r←e toutes les <sexpr> telles que (symbolp <sexpr>) =/ () et que le mode`le (Cons symbol (Vector cons symbol)) ←f←i←l←t←r←e toutes les <sexpr> de la forme (<symbol> . #[(<sexpr> . <sexpr>) <symbol>]) Plus ge'ne'ralement, nous dirons qu'un mode`le model ←f←i←l←t←r←e une s- expression sexpr ou, de manie`re e'quivalente, que sexpr ←e←s←t ←u←n←e ←i←n←s←t←a←n←c←e de model si et seulement si: 13 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← model ←f←i←l←t←r←e sexpr model condition ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← modelname la valeur de mode`le de modelname ←f←i←l←t←r←e sexpr ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol model1 ...) model1 ←f←i←l←t←r←e sexpr ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Predicate fun init) (funcall fun sexpr) =/ () ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (List model1) sexpr = (sexpr1 ... sexprn) model1 ←f←i←l←t←r←e sexpri ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Cons model1 model2) sexpr = (sexpr1 . sexpr2) model1 ←f←i←l←t←r←e sexpr1 model2 ←f←i←l←t←r←e sexpr2 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Vector model1 ... modeln) sexpr = #[sexpr1 ... sexprn] modeli ←f←i←l←t←r←e sexpri ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Exemples symbol ←f←i←l←t←r←e car cons ←f←i←l←t←r←e (1 . 2) lnumber ←f←i←l←t←r←e (1 2 3 4) point ←f←i←l←t←r←e (1 . 2) segment ←f←i←l←t←r←e #[(0 . 0) (10 . 90)] A cette relation de filtrage, nous associons une construction Lisp: 14 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les (omatchq <modelname> <sexpr>) Cette fonction, qui n'e'value pas son premier argument, renvoie une valeur diffe'rente de () si et seulement si <modelname> ←f←i←l←t←r←e <sexpr>. Exemples ? (omatchq symbol 'car) = t ? (omatchq number 'car) = () ? (omatchq number 1) = 1 ? (omatchq lnumber '(1 2 3 4)) = t ? (omatchq lnumber '(1 2 a 3)) = () ? (omatchq point '(1 . 2)) = 2 ? (omatchq point 'a) = () ? (omatchq segment '#[(0 . 0) (10 . 90)]) = t ? (omatchq segment '#[(0 . 1) (a . 0)]) = () ? (de always-true (x) t) = always-true ? (defmodel * (Predicate always-true ())) = * ? (omatchq * '(1 #[1 (2 . 3)])) = t 15 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les 1.2.2.2 De'structuration Les mode`les sont ensuite des ←s←c←h←e'←m←a←s ←d←e ←d←e'←s←t←r←u←c←t←u←r←a←t←i←o←n de <sexpr>. Nous dirons que symbol ←e←s←t ←u←n ←c←h←a←m←p de model si et seulement si: ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← symbol ←e←s←t ←u←n ←c←h←a←m←p de model model condition ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← modelname symbol ←e←s←t ←u←n ←c←h←a←m←p de la valeur de mode`le de modelname ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol1) (eq symbol symbol1) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol1 model1 ...) ou (eq symbol symbol1) ou symbol ←e←s←t ←u←n ←c←h←a←m←p de model1 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Cons model1 model2) ou symbol ←e←s←t ←u←n ←c←h←a←m←p de model1 ou symbol ←e←s←t ←u←n ←c←h←a←m←p de model2 ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Vector model1 ... modeln) ou symbol ←e←s←t ←u←n ←c←h←a←m←p de model1 ... ou symbol ←e←s←t ←u←n ←c←h←a←m←p de modeln ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Dans les cas ou` modeli est un nom de mode`le modelname, on ne descend pas dans la valeur de mode`le de modelname. Exemples car ←e←s←t ←u←n ←c←h←a←m←p de cons x ←e←s←t ←u←n ←c←h←a←m←p de point org ←e←s←t ←u←n ←c←h←a←m←p de segment xext ←e←s←t ←u←n ←c←h←a←m←p de segment Dans le cas ou` une s-expression <sexpr> ←e←s←t ←i←n←s←t←a←n←c←e du mode`le <model> et ou` le symbole <symbol> ←e←s←t ←u←n ←c←h←a←m←p du mode`le <model>, nous de'finissons la valeur du champ <symbol> de l'instance 16 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les <sexpr>: ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← valeur d'un champ = f (model symbol sexpr) model condition valeur ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← modelname f (valeur de mode`le de model1 symbol sexpr) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol1 ...) (eq symbol symbol1) sexpr ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol1 model1 ...) (neq symbol symbol1) f (model1 symbol sexpr) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Cons model1 model2) symbol ←e←s←t ←u←n ←c←h←a←m←p de model1 (car f (model1 symbol sexpr)) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Cons model1 model2) symbol ←e←s←t ←u←n ←c←h←a←m←p de model2 (cdr f (model1 symbol sexpr)) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Vector model1 ... modeln) symbol ←e←s←t ←u←n ←c←h←a←m←p de modeli (vref i f (modeli symbol sexpr)) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ou` car,cdr et vref sont les constructions Lisp permettant de de'structurer les cellules cons et les cellules vectors. Nous donnons des constructions Lisp permettant de consulter ou de modifier des valeurs de champs. (ogetq <modelname> <fieldname> <sexpr>) Les deux premiers arguments ne sont pas e'value's, <sexpr> ←e←s←t ←i←n←s←t←a←n←c←e de <modelname> et <fieldname> ←e←s←t ←u←n ←c←h←a←m←p de <modelname>. Cette construction rame`ne en valeur la valeur du champ <fieldname> de l'instance <sexpr>. (oputq <modelname> <fieldname> <sexpr> <val>) Les deux premiers arguments ne sont pas e'value's, <sexpr> ←e←s←t ←i←n←s←t←a←n←c←e de <modelname> et <fieldname> ←e←s←t ←u←n ←c←h←a←m←p de <modelname>. Cette construction met dans la valeur du champ <fieldname> de l'instance <sexpr> la s-expression <val>. Ceci est re'alise' par les fonctions idoines de modification physique 17 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les rplaca, rplacd et vset. Exemples ? (setq p '(1 . 2)) = (1 . 2) ? (ogetq point x p) = 1 ? (oputq point y p 25) = (1 . 25) ? (ogetq point y p) = 25 ? (setq p1 '(10 . 10)) = (10 . 10) ? (setq seg (vector p p1)) = #[(1 . 25) (10 . 10)] ? (ogetq segment org seg) = (1 . 25) ? (ogetq segment xorg seg) = 1 ? (oputq segment xorg seg 22) = (22 . 25) ? seg = #[(22 . 25) (10 . 10)] ? (ogetq segment ext seg) = (10 . 10) 1.2.2.3 Instantiation Les mode`les sont enfin des ←s←c←h←e'←m←a←s ←d←e ←c←o←n←s←t←r←u←c←t←i←o←n des sexpr. Nous de'finissons la valeur par de'faut d'un mode`le: 18 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← de'faut (model) model valeur ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← modelname de'faut (valeur de mode`le de modelname) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol) () ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol model1) de'faut (model1) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Field symbol model1 sexpr) (eval sexpr) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Predicate fun init) (eval init) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (List model1) () ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Cons model1 model2) (cons de'faut (model1) de'faut (model2)) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Vector model1 ... modeln) (vector de'faut (model1) ... de'faut (modeln)) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | sauf dans le cas ou` modeli est un nom de mode`le, auquel cas cette valeur par de'faut vaut (). ou` cons et vector sont les fonctions Lisp de cre'ation de cellules cons et de vectors. Exemples de'faut (symbol) = nil de'faut (cons) = (()) de'faut (number) = 0 de'faut (lnumber) = () de'faut (point) = (0 . 0) de'faut (vector) = #[(0 . 0) . (0 . 0)] Nous de'finissons une construction Lisp permettant de cre'er des instances de mode`les. 19 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les (omakeq <modelname> <fieldname>1 <sexpr>1 ... <fieldname>n <sexpr>n) Ni <modelname>, ni les <fieldname>i ne sont e'value's. Cette fonction rame`ne en valeur une instance de <modelname> qui est une copie de de'faut (<modelname>) dont les champs <fieldname>i ont e'te' mis aux valeurs <sexpr>i. Nous de'finissons e'galement une version restreint qui e'value son argument: (omake <modelname>) Cette fonction rame`ne en valeur une instance de <modelname> qui est une copie de de'faut (<modelname>). Exemples ? (omakeq symbol) = nil ? (omakeq number) = 0 ? (omakeq segment) = #[(0 . 0) (0 . 0)] ? (omake 'segment) = #[(0 . 0) (0 . 0)] ? (setq seg (omakeq segment xorg 10 yorg 20 xext 30 yext 40)) = #[(10 . 20) (30 . 40)] ? (ogetq segment org seg) = (10 . 20) ? (setq seg1 (omakeq segment org (omakeq point x 0 y 0) ? xext 3 yext 4))) = #[(0 . 0) (3 . 4)] 20 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les 1.2.3 Les Macro Mode`les Nous de'finissons des nouvelles expressions de notre langage de mode`les: les macro mode`les <modelx>. <modelx> = (Alter <model> <fieldname>1 <model>1 ... <fieldname>n <model>n) (Include <modelname>) (Extend <model> <fieldname>1 (Vector <model>11 ... <model>p1) ... <fieldname>n (Vector <model>1n ... <model>pn)) Ces mode`les portent le nom de ←m←a←c←r←o mode`les car, avant de les interpre'ter, Ceyx leur applique une expansion, c'est a` dire une transformation de ces expressions dans le langage de mode`les de base. Leur se'mantique sera donc parfaitement de'fini lorsque que nous aurons de'crit la re`gle d'expansion. Dans ce qui suit, les <fieldname>i ←s←o←n←t ←d←e←s ←c←h←a←m←p←s du mode`le <model>. ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← Expansion des Macro Mode`les Mode`le Expansion ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Alter <model> <fieldname>1 <model>1 ... <fieldname>n <model>n) <model> ou` (Field <fieldname>i ...) est remplace' par <model>i ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← (Include <modelname>) valeur de mode`le de <modelname> ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← 21 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les (Extend <model> <fieldname>1 (Vector <model>11 ... <model>p1) ... <fieldname>n (Vector <model>1n ... <model>qn)) <model> ou` (Field <fieldname>i (Vector <model>1i' ... <model>ri') ...) est remplace' par (Field <fieldname>i (Vector <model>1i' ... <model>ri' <model>1i ... <model>mi)) ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On notera que pour la construction Extend, l'expansion ne peut se faire que si les champs a` e'tendre sont de'ja` des vectors. On comprendra ces constructions sans difficulte's sur des exemples. Exemples ? (defmodel bipoint ? (Alter point ? x (Field org ? (Alter point ? x (Field xorg number 0) ? y (Field yorg number 0))) ? y (Field ext ? (Alter point ? x (Field xext number 0) ? y (Field yext number 0))))) = bipoint ? (setq bipoint (omakeq bipoint xorg 1 yorg 2 ext (omakeq point))) = ((1 . 2) 0 . 0) ? (oputq bipoint xext bipoint 4) = (4 . 0) ? (ogetq bipoint org bipoint) = (1 . 2) ? (defmodel named-point ? (Cons (Field name) (Field point (Include point)))) = named-point ? (omakeq named-point name 'p x 1 y 2) = (p 1 . 2) 22 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les ? (defmodel A (Field attributs (Vector))) = A ? (omakeq A) = #[] ? (defmodel A1 ? (Extend A ? attributs (Vector (Field a1)))) = A1 ? (omakeq A1 a1 1) = #[1] ? (omatchq A (omakeq A1)) = t ? (omatchq A1 (omakeq A)) = () ? (defmodel A3 ? (Extend A1 ? attributs (Vector (Field a2) (Field a3)))) = A3 ? (setq a (omakeq A3 a1 1 a2 2 a3 3)) = #[1 2 3] ? (ogetq A3 a1 a) = 1 ? (omatchq A1 a) = t ? (ogetq A1 a1 a) = 1 23 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les 1.3 De'finition de Mode`les Nous de'finissons dans cette partie trois constructions Lisp fondamentales pour le programmeur Ceyx. Il s'agit des constructions: o+ defmodel, qui associe a` un symbole Lisp une de'finition de mode`le; o+ defaccess, qui de'finit des fonctions Lisp permettant d'acce'der en lecture/e'criture aux valeurs des champs des instances d'un mode`le. Pour des commodite's d'e'criture, il est pre'fe'rable d'utiliser ces fonctions que les constructions ge'ne'rales ogetq et oputq; o+ defmake, qui de'finit une fonction Lisp de cre'ation d'instances d'un mode`le, prenant comme argument un sous-ensemble se'lectionne' de ses champs. Encore une fois il est pre'fe'rable d'utiliser des fonctions de cre'ation ainsi de'finies que la construction ge'ne'rale omakeq. 1.3.1 La Construction defmodel Nous avons de'ja` rencontre' et utilise' la construction defmodel, qui est en quelque sorte la primitive d'affectation dans le langage de mode`les. Nous la de'finissons ici en tant que construction Lisp. (defmodel <name> <model>) Cette fonction, qui n'e'value aucun de ses arguments, associe au symbole <name> une valeur de mode`le <model>. De manie`re interne une certaine repre'sentation de <model> est place'e dans le champ objval de <name>. 24 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les Nous avons de'ja` donne' de nombreux exemples d'utilisation de cette construction dans les sections pre'ce'dentes. Exemples ? (defmodel fiche ? (Cons ? (Cons (Field nom symbol) ? (Field prenom symbol)) ? (Cons (Field adresse string) ? (Field attributs (Vector))))) = fiche ? (setq fiche-monsieur (omakeq fiche nom 'Jacquemart prenom 'Marcel)) = ((Jacquemart . Marcel) () . #[]) 1.3.2 La Construction defaccess (defaccess <modelname> <fieldname>1 ... <fieldname>n) Aucun argument n'est e'value'. Cette construction ame`ne a` la de'finition des n fonctions d'acce`s de nom #:<modelname>:<fieldname>i, i.e. <fieldname>i dans l'espace de noms (package) <modelname>. Ces fonctions prennent un (lecture) ou deux (e'criture) arguments, elles permettent d'acce'der en lecture/e'criture aux valeurs des champs de l'instance de <modelname> passe'e en argument. Dans le cas ou` n=0 (pas de nom de champ passe' en argument), les fonctions d'acce`s a` tous les champs de <modelname> sont engendre'es. Exemples ? fiche-monsieur = ((Jacquemart . Marcel) () . #[]) 25 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les ? (defaccess fiche nom prenom adresse) = fiche ? ; Les fonctions de'finies par cet appel sont: ? ; ? ; #:fiche:nom ? ; #:fiche:prenom ? ; #:fiche:adresse ? ({fiche}:nom fiche-monsieur) = Jacquemart ? ({fiche}:prenom fiche-monsieur) = Marcel ? ({fiche}:adresse fiche-monsieur "Sans domicile fixe") = (Sans domicile fixe . #[]) ? ({fiche}:adresse fiche-monsieur) = Sans domicile fixe ? fiche-monsieur = ((Jacquemart . Marcel) Sans domicile fixe . #[]) ? (defmodel point (Cons (Field x number 0) (Field y number 0))) = point ? (defaccess point) = point ? ; Les fonctions de'finies par cet appel sont: ? ; ? ; #:point:x ? ; #:point:y 1.3.3 La Construction defmake (defmake <modelname> <mkname> (<fieldname>1 ... <fieldname>n)) (defmake <modelname> <mkname>) Aucun argument n'est e'value'. Dans le premier cas, cette construction de'finit une fonction de nom <mkname> prenant n arguments <arg>i et renvoyant en valeur une instance de <modelname> dont les champs <fieldname>i ont pour valeurs <arg>i. De me↑me que pour la fonction de, il est possible de passer 26 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les les arguments sous forme d'arbre. Dans le second cas, aucune fonction n'est engendre'e, mais la fonction de nom <mkname> est de'clare'e comme fonction de construction du mode`le <modelname>. Cette information est utilise'e par la construction describe. Exemples ? (defmake fiche fiche (nom prenom)) = fiche ? (pretty fiche) (de fiche (nom prenom) (cons (cons nom prenom) (copy '(() . #[])))) = () ? (setq fiche-madame (fiche 'Dugland 'Yvette)) = ((Dugland . Yvette) () . #[]) ? (defmake point mkpoint (x y)) = mkpoint ? (pretty mkpoint) (de mkpoint (x y) (cons x y)) = () ? (mkpoint 1 2) = (1 . 2) ? (defmodel liste-nommee ? (Cons (Field nom symbol) ? (Field liste (List *)))) = liste-nommee ? (defmake liste-nommee liste-nommee (nom . liste)) = liste-nommee ? (pretty liste-nommee) (de liste-nommee (nom . liste) (cons nom liste)) = () ? (liste-nommee 'toto 'a 'b 'c) = (toto a b c) ? (defmake liste-nommee faire-liste-nommee liste) = faire-liste-nommee 27 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les ? (pretty faire-liste-nommee) (de faire-liste-nommee liste (cons () liste)) = () ? (faire-liste-nommee 1 2 3) = (() 1 2 3) 1.3.4 Les Mode`les Pre'de'finis Un certain nombre de mode`les sont de'finis a` l'initialisation de Ceyx, nous les de'crivons ci-dessous. Tout d'abord le mode`le *, qui filtre toutes les s-expressions Lisp (defmodel * (Predicate always-true ())) (de always-true (x) t) puis les types primitifs Lisp: (defmodel null (Predicate null ())) (defmodel symbol (Predicate symbolp 'nil)) (defmodel fix (Predicate fixp 0)) (defmodel float (Predicate floatp 0.)) (defmodel number (Predicate numberp 0)) (defmodel string (Predicate stringp "")) (defmodel atom (Predicate atomp nil)) (defmodel cons (Cons (Field car) (Field cdr))) (defmodel vector (Predicate vectorp #[])) (defmodel integer (Predicate numberp 0)) 28 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les 1.4 Les Espaces Se'mantiques 1.4.1 Les Espaces de Noms L'espace des symboles en Le←Lisp est organise' de manie`re arborescente. Ainsi quand le lecteur Lisp voit stop il s'agit pour lui du symbole de ←p←n←a←m←e "stop" dans l'espace de nom (package) global ||. Quand il voit #:compilateur:stop il sagit du symbole de ←p←n←a←m←e "stop" dans l'espace de nom appele' compilateur. Hie'rarchiser ainsi l'espace des symboles permet classiquement de se pre'server des conflits de noms entre deux programmes. Ainsi stop est-il le symbole stop habituel et #:compilateur:stop est-il le symbole stop du compilateur. Nous de'finissons une construction permettant de de'terminer si un symbole est dans l'espace de nom d'un autre symbole. (<=p <symbol>1 <symbol>2) Cette fonction rame`ne une valeur diffe'rente de (), si et seulement si si <symbol>1 posse'de dans ses espaces de noms parents <symbol>2. Cette fonction peut e↑tre de'finie en Lisp par: (de <=p (pkg1 pkg2) (if (eq pkg1 pkg2) t (if (eq pkg1 '||) nil (<=p (packagecell pkg1) pkg2)))) 29 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les Exemples ? (<=p '#:toto:tata:titi:tutu '#:toto:tata) = t Le proble`me qui se pose tre`s vite quand on veut utiliser de manie`re intensive la hie'rarchie des packages est un proble`me d'e'criture: il devient vite pe'nible d'e'crire de tros longues chai↑nes d'acce`s #:toto:tata:titi:tutu:tete:tyty:mafonction Pour aider re'soudre ce proble`me, nous introduisons la notion d'abbre'viation. (defabbrev <full-name> <abbrev>) Cette fonction qui n'e'value ses arguments stocke dans la pliste de <abbrev> le symbole <full-name>, information qui est accessible a` l'utilisateur par la fonction plink. Le symbole <abbrev> est appele' une abbre'viation de <full-name>. Les abbre'viations sont utilise'es par le lecteur Lisp en conjonction avec les accolades {} qui sont donc de ce fait des caracte`res re'serve's: {<abbrev>} est lu comme <full-name> si <abbrev> est une abbre'viation de <full-name> et comme <abbrev> dans le cas contraire. (plink <abbrev>) L'argument <abbrev> est e'value', sa valeur doit e↑tre un symbole. Si la valeur de <abbrev> a e'te' de'finie comme une abbre'viation de <full-name>, ce dernier est renvoye' en valeur, sinon la valeur de <abbrev> est renvoye'e. Exemples 30 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les ? '{toto} = toto ? '{toto}:a = #:toto:a ? (defabbrev #:t:o:t:o toto) = #:t:o:t:o ? '{toto} = #:t:o:t:o ? (plink 'toto) = #:t:o:t:o ? '{toto}:ah:la:la = #:t:o:t:o:ah:la:la Nous e'tendons la construction defmodel de manie`re a` ge'ne'rer une abbre'viation a` la demande. (defmodel (<name> <abbrev>) <model>) Cette construction est e'quivalente a`: (defmodel <name> <model>) (defabbrev <name> <abbrev>) Exemples ? (defmodel (#:toto:tata:titi titi) ? (Cons (Field a) (Field b))) = #:toto:tata:titi ? '{titi} = #:toto:tata:titi ? (defmake {titi} titi (a b)) = titi ? (setq x (titi 1 2)) = (1 . 2) ? '({titi}:a x) = (#:toto:tata:titi:a x) ? ({titi}:a x) ** eval : fonction indefinie : #:toto:tata:titi:a 31 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les [stack 3] (lock ...) [stack 2] (tag #:system:error-tag ...) [stack 1] (itsoft ...) ? (defaccess {titi}) = #:toto:tata:titi ? ({titi}:a x) = 1 ? ; une utilisation pour faire du franglais ? (defmodel (Book Livre) ? (Vector ? (Field chapters (Field chapitres)) ? (Field title (Field titre)))) = Book ? (defaccess Book) = Book ? (defmake Book Book (chapters title)) = Book ? (defmake {Livre} Livre (chapitres titre)) = Livre ? (setq b (Book '(1 2 3) "Paris by Night")) = #[(1 2 3) Paris by Night] ? ({Livre}:titre b) = Paris by Night ? ({Livre}:chapters b) = (1 2 3) 1.4.2 Les Proprie'te's Se'mantiques des Mode`les Nous avons de'ja vu comment la construction defaccess produit des fonctions d'acce`s aux instances d'un mode`le, dont les noms sont des symboles interne's dans l'espace de noms canoniquement associe' au mode`le. Ainsi, pour le mode`le fiche, les fonctions d'acce`s #:fiche:nom #:fiche:prenom #:fiche:adresse 32 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les sont elles de'finies. Nous ge'ne'ralisons cette situation en de'finissant les ←p←r←o←p←r←i←e'←t←e'←s ←s←e'←m←a←n←t←i←q←u←e←s d'un mode`le comme e'tant l'ensemble des fonctions de'finies dans l'espace de noms du mode`le. Ainsi de'finir une proprie'te' se'mantique du mode`le model revient-il a` de'finir une fonction Lisp classique dans l'espace de nom du mode`le. Exemples ? (de #:fiche:imprime (fiche) ? (print "Nom: " (#:fiche:nom fiche)) ? (print "Prenom: " (#:fiche:prenom fiche)) ? (when (#:fiche:adresse fiche) ? (print "Adresse: " (#:fiche:adresse fiche))) ? (#:fiche:nom fiche)) = #:fiche:imprime ? (#:fiche:imprime fiche-monsieur) Nom: Jacquemart Prenom: Marcel Adresse: Sans domicile fixe = Jacquemart ? (#:fiche:imprime fiche-madame) Nom: Dugland Prenom: Yvette = Dugland Les ←p←r←o←p←r←i←e'←t←e'←s ←s←e'←m←a←n←t←i←q←u←e←s d'un mode`le constituent en quelque sorte son ←m←o←d←e ←d'←e←m←p←l←o←i: comment acce`der aux champs des instances, comment imprimer ces instances, comment les e'diter, etc... ←I←l ←e←s←t ←d←e ←b←o←n ←t←o←n ←e←n ←C←e←y←x ←d←e ←c←o←n←s←i←d←e'←r←e←r ←q←u←e ←l←e ←p←r←e←m←i←e←r ←a←r←g←u←m←e←n←t ←d'←u←n←e ←p←r←o←p←r←i←e'←t←e' ←s←e'←m←a←n←t←i←q←u←e ←e←s←t ←u←n←e ←i←n←s←t←a←n←c←e ←d←u ←m←o←d←e`←l←e ←s←u←r ←l←e←q←u←e←l ←o←n ←d←e'←f←i←n←i←t ←c←e←t←t←e ←p←r←o←p←r←i←e'←t←e' ←s←e'←m←a←n←t←i←q←u←e. ←L←a ←r←a←i←s←o←n ←e←n ←a←p←p←a←r←a←i↑←t←r←a ←c←l←a←i←r←e←m←e←n←t ←l←o←r←s ←d←e ←l'←i←n←t←r←o←d←u←c←t←i←o←n ←d←e ←l←a ←c←o←n←s←t←r←u←c←t←i←o←n ←s←e←n←d ←a←u ←c←h←a←p←i←t←r←e ←s←u←i←v←a←n←t. 33 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les 1.4.3 Re'cupe'ration Fonctionnelle Hie'rarchique Nous avons vu plus haut que les espaces de noms Le←Lisp sont organise's de manie`re arborescente. Ceci se traduit en Ceyx par une organisation hie'rarchique des espaces se'mantiques associe's aux mode`les. Reprenons l'exemple du mode`le fiche de'fini par ? (defmodel fiche ? (Cons ? (Cons (Field nom symbol) ? (Field prenom symbol)) ? (Cons (Field adresse string) ? (Field attributs (Vector))))) = fiche et de'finissons maintenant une fiche spe'ciale qui est celle que voudrait utiliser un cordonnier: ? (defmodel {fiche}:fiche-cordonnier ? (Extend fiche ? attributs (Vector (Field pointure fix)))) = #:fiche:fiche-cordonnier Toutes les instances de ce nouveau mode`le posse`dent les champs nom, pre'nom, adresse, attributs du mode`le fiche et les fonctions d'acce`s de'finies sur fiche par la construction defaccess sont applicables aux instances du mode`le #:fiche:fiche-cordonnier. Plus ge'ne'ralement, toutes les proprie'te's se'mantiques de fiche sont applicables aux instances du mode`le #:fiche:fiche- cordonnier. Nous dirons que ce nouveau mode`le ←h←e'←r←i←t←e des proprie'te's se'mantiques du mode`le fiche. La fonction Le←Lisp getfn permet de de'terminer si une proprie'te' se'mantique est de'finie dans un espace de noms ou bien dans l'un de ses ance↑tres: 34 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les (getfn <pkg> <sym> <lastpkg>) (getfn <pkg> <sym>) Cette fonction cherche si le symbole de nom <sym> posse`de une de'finition de fonction dans le package <pkg> et, s'il n'en existe pas, dans ses packages pe`res jusqu'au package <lastpkg> exclus. Dans le cas ou` <lastpkg> n'est pas spe'cifie', on remonte jusqu'au package global || inclus. Cette construction rame`ne le nom de la fonction si elle existe et () autrement. En Ceyx, nous utiliserons une version spe'ciale de la fonction getfn: ({Ceyx}:getfn <pkg> <sym>) Cette fonction a un comportement analogue a` getfn, sinon que la recherche est effectue'e dans un premier temps jusuq'au package || exclus puis en cas d'e'chec dans le package * et enfin dans le package ||. Cette fonction peut e↑tre de'crite en Lisp par: (de #:Ceyx:getfn (package fun) (or (getfn package fun '||) (getfn '* fun))) Pour faciliter l'usage de cette construction, nous de'finissons les constructions semcall et hfuncall. (hfuncall <pkg> <sym> <arg>1 ... <arg>n) Tous les arguments sont e'value's, cette construction peut e↑tre de'finie en Lisp par: (de hfuncall (pkg sym . args) (apply ({Ceyx}:getfn pkg sym) args)) 35 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les (semcall <pkg> <sym> <arg>1 ... <arg>n) Analogue a` la pre'ce'dente sinon qu'on passe par le plink de <pkg>. (de semcall (pkg sym . args) (apply ({Ceyx}:getfn (plink pkg) sym) args)) La re'cupe'ration fonctionnelle hie'rarchique est surtout utilise'e en conjugaison avec les objets auto-type's de'finis au chapitre suivant. 1.5 Description de Mode`les Nous donnons ici des fonctions permettant de de'crire interactivement un mode`le, c'est a` dire tant sa structure que son espace se'mantique. (mdescribe <modelname> [<prof>]) Cette fonction, qui n'e'value pas ses arguments imprime sur le terminal la description du mode`le <modelname> et de tous ses sous-mode`les jusqu'a` la profondeur <prof>. Si l'argument optionnel <prof> n'est pas donne' on ne de'crit que le mode`le lui-me↑me. (tbl-describe <modelname>) L'argument n'est pas e'value'. Une description du mode`le <modelname> est imprime'e sur le terminal sous la forme d'une spe'cification pour troff/tbl. Tre`s utile pour les documentations quand on travaille sous Unix. 36 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les (apropos <package>) Liste toutes les fonctions de l'espace de nom package. (describe <object> [<modelname>]) Les arguments sont e'value's et une description de <object> est imprime'e sur le terminal. Dans le cas ou` l'argument optionnel n'est pas donne', l'objet est de'crit suivant son type (voir chapitre suivant), sinon il est de'crit en supposant qu'il est une instance de <modelname>. Exemples : (defmodel toto (Cons (Field a symbol) (Field b number))) = toto : (mdescribe toto) Modele: toto Champs: a ~ symbol b ~ number = () : (defaccess toto) = toto : (mdescribe toto) Modele: toto Champs: a ~ symbol b ~ number Proprietes Semantiques: a obj b obj 37 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les = () : (defmake toto mktoto (a b)) = mktoto : (mdescribe toto) Modele: toto Fonctions de Cre'ation: mktoto (a b) Champs: a ~ symbol b ~ number Proprietes Semantiques: a obj b obj = () : (de {toto}:print (x) : (print "a: " ({toto}:a x)) : (print "b " ({toto}:b x))) = #:toto:print : (mdescribe toto) Modele: toto Fonctions de Cre'ation: mktoto (a b) Champs: a ~ symbol b ~ number Proprietes Semantiques: a obj b obj print (x) = () : (defmodel ({toto}:tata tata) 38 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les : (Alter toto a (Cons (Field a1) (Field a2)))) = #:toto:tata : (defaccess {tata}) = #:toto:tata : (mdescribe toto) Modele: toto Fonctions de Cre'ation: mktoto (a b) Champs: a ~ symbol b ~ number Proprietes Semantiques: a obj b obj print (x) Sous Modeles: tata = () : (mdescribe {tata}) Modele: #:toto:tata Abreviations: tata Champs: a ~ (Cons ...) a1 ~ * a2 ~ * b ~ number Proprietes Semantiques: a obj a1 obj a2 obj 39 Mercredi 3 Octobre 1984 Programmer en Ceyx 1: Les Mode`les b obj = () : (tbl-describe toto) ←←←←←←←←←←←←←←←←←←←←←←←← Le Mode`le: toto ←←←←←←←←←←←←←←←←←←←←←←←← ←←←←←←←←←←←←←←←←←←←←←←←← Fonction de Cre'ation mktoto (a b) ←←←←←←←←←←←←←←←←←←←←←←←← Champs a symbol b number ←←←←←←←←←←←←←←←←←←←←←←←← Proprie'te's Se'mantiques a obj b obj print (x) ←←←←←←←←←←←←←←←←←←←←←←←← Sous Mode`le tata ←←←←←←←←←←←←←←←←←←←←←←←← | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | : (describe (mktoto 1 2) 'toto) (1 . 2) est une instance du modele toto Ses diffe'rents champs valent: a: 1 b: 2 = t 40 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types C H A P I T R E 2 Les Types ←J←e←a←n-←M←a←r←i←e ←H←u←l←l←o←t Ceyx permet un style de programmation oriente'e objets a` la SmallTalk. On peut re'sumer le principe de fonctionnement d'un tel langage de la manie`re suivante: o+ a` chaque type est associe' un espace se'mantique, c'est a` dire un ensemble de fonctions de manipulations spe'cifiques aux instances de ce type, o+ les types sont organise's de manie`re hie'rarchique, un sous type he'ritant des espaces se'mantiques de ses parents, o+ tous les objets manipule's sont auto-type's, o+ pour appliquer une fonction de manipulation a` une instance, on lui envoie en message le nom de la fonction et ses arguments. L'objet, qui connait son type, n'a donc plus qu'a` chercher dans l'espace se'mantique associe' a` ce type la fonction voulue. Le chapitre pre'ce'dent a montre' comment de'finir des espaces se'mantiques hie'rarchiques, nous introduisons maintenant les notions de type, d'objets auto-type's et d'envoi de message. On de'finit un type en Ceyx de la me↑me manie`re qu'on de'finit un mode`le, mais en utilisant la construction deftype en lieu et place de defmodel. Nous pouvons de'finir le type Point par: ? (deftype Point (Cons (Field x fix 0) (Field y fix 0))) 41 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types = Point La seule et unique diffe'rence entre mode`les et types est que les instances des seconds sont e'tiquette'es par le nom du type qui les a engendre'es. Cet e'tiquettage est re'alise'e en utilisant des cellules cons spe'ciales (tcons) qui s'imprime sous la forme #( . ) au lieu de ( . ). ? (defmake Point mkpoint (x y)) = mkpoint ? (setq p (mkpoint 5 6)) = #(Point 5 . 6) Le type d'un objet est soit son type Lisp (symbol, cons, vector ...), s'il n'est pas une cellule e'tiquette'e, soit le car de cette cellule e'tiquette'e: ? (type 1) = fix ? (type '(1 . 2)) = cons ? (type p) = Point Un des avantages essentiels des objets auto-type's est qu'a` partir du nom du type qui les a engendre's, ils ont acce`s a` l'espace se'mantique associe' a` ce nom. Ainsi si on envoie a` une instance de Point le ←m←e←s←s←a←g←e translate avec les argument dx et dy, cette instance est a` me↑me de de'couvrir elle-me↑me qu'il faut appliquer la fonction #:Point:translate, si toutefois elle existe. C'est l'objet de la construction send. ? (defaccess Point) = Point ? (de {Point}:translate (point dx dy) ? (send 'x point (+ dx (send 'x point))) ? (send 'y point (+ dy (send 'y point))) ? point) 42 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types = #:Point:translate ? (send 'translate p 3 4) = #(Point 8 . 10) 2.1 Les Types Lisp Les types Lisp de base correspondent aux diverses formes que peuvent avoir les s-expressions. Lisp est a` me↑me de reconnai↑tre les types: - symbol, - fix, - float, - string, - cons, - vector, a` l'aide des pre'dicats symbolp, fixp, floatp, stringp, consp et vectorp. Dans la suite nous conside'rons que () est de type null, reconnu par le pre'dicat null. Nous avons vu au chapitre pre'ce'dent comment construire des mode`les. Par exemple nous avons de'fini le mode`le Coord par: (defmodel Coord (Cons (Field x fix 0) (Field y fix 0))) et une fonction de cre'ation de ce mode`le par: (defmake Coord Coord (x y)) Si nous construisons maintenant une instance du mode`le Coord: ? (setq c (Coord 3 4)) = (3 . 4) 43 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types Cette instance c est de type cons, et nous n'avons aucune information sur le fait que c est une instance du mode`le Coord. Notre but dans ce chapitre est de donner une extension au langage de mode`les permettant de de'finir des objets Lisp portant leur marque de fabrique, c'est a` dire gardant trace du mode`le dont ils sont instances. 2.2 Les Types Ceyx 2.2.1 Les Objets Nous de'finissons les "objets" par extension du langage de s- expressions: <object> = <object> |#(<symbol> . <object>) Nous de'finissons une fonction de construction Lisp associe'e: (tcons <symbol> <sexpr>) Cette fonction est en tout point analogue au cons, sinon que les paires pointe'es construites sont e'tiquette'es, i.e. sont reconnaissables par le pre'dicat tconsp. ? (tcons 'a 'b) = #(a . b) ? (cons 'a 'b) = (a . b) 44 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types (tconsp <obj>) Cette fonction renvoie une valeur diffe'rente de () si et seulement si <obj> est une cellule e'tiquette'e. ? (tconsp (tcons 'a 'b)) = #(a . b) ? (tconsp (cons 'a 'b)) = () Dans une incarnation du langage Lisp telle que Le←Lisp, la construction tcons a e'te' introduite dans le noyau du langage pour les besoins de Ceyx. La construction tcons peut e↑tre imple'mente'e de manie`re efficace sur ZetaLisp, en utilisant une zone d'allocation spe'ciale pour les cellules e'tiquette'es. Dans d'autres syte`mes Lisp (MacLisp, FranzLisp, ...), une bonne imple'mentation est difficile a` re'aliser. 2.2.2 La Contruction deftype Paralle`lement a` cette extension du langage de s-expressions, nous e'tendons le langage de mode`les en introduisant le mode`le Tcons: <model> = ... | (Tcons <symbol> <object>) Ce nouveau mode`le joue un ro↑le tre`s particulier en Ceyx, c'est pourquoi il n'est introduit dans le langage de mode`les que de manie`re interne et n'est utilisable en standard que par l'interme'diaire de la construction deftype. Le mode`le Tcons est utilise' pour de'crire des mode`les particuliers que nous appelons ←t←y←p←e←s, dont la particularite' est que les instances sont des cellules tcons, dont la partie gauche contient le nom du mode`le dont l'objet est instance et dont la partie droite contient la repre'sentation de cette instance. Nous introduisons la construction deftype qui permet de de'finir des types Ceyx ou mode`les auto-type's. 45 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types (deftype <name> <model>) (deftype (<name> <abbrev>) <model>) Cette fonction, qui n'e'value aucun de ses arguments, associe au symbole <name> une valeur de mode`le obtenue de la fac,on suivante: si <model> = (Tcons <symbol> <model>1) alors (Tcons <name> <model>1) sinon (Tcons <name> <model>) Comme pour defmodel, on peut donner une abbre'viation <abbrev> pour le type <name>. Exemples ? (deftype Art (Cons (Field x fix 0) (Field y fix 0))) = Art ? (defmake Art Art (x y)) = Art ? (setq x (Art 1 2)) = #(Art 1 . 2) La se'mantique du Mode`le Tcons sera parfaitement de'finie quand nous aurons dit comment il re'agit a` la construction omatchq: (omatchq <type> <object>) =/ () ssi (tconsp <object>) et (<=p (tcar <object>) <type>) c'est a` dire qu'un objet <object> est instance d'un type <type> si et seulement si <object> est un tcons dont le car est un symbole infe'rieur au sens de la hie'rarchie des packages a` <type>. Exemples ? (deftype fiche ? (Cons ? (Cons (Field nom) (Field prenom)) 46 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types ? (Field caracteristiques (Vector)))) = fiche ? (defaccess fiche) = fiche ? (defmake fiche fiche (nom prenom)) = fiche ? (deftype ({fiche}:fiche-cordonnier fiche-cordonnier) ? (Extend fiche ? caracteristiques ? (Vector (Field adresse) ? (Field pointure)))) = fiche-cordonnier ? (defaccess {fiche-cordonnier} adresse pointure) = #:fiche:fiche-cordonnier ? (defmake {fiche-cordonnier} fiche-cordonnier (nom prenom adresse pointure)) = fiche-cordonnier ? (setq x (fiche-cordonnier 'Jacquemart 'Marcel "Inconnue" 48)) = #(#:fiche:fiche-cordonnier (Jacquemart . Marcel) . #[Inconnue 48]) ? (omatchq fiche-cordonnier x) = t ? (omatchq fiche x) = t ? (omatchq fiche-cordonnier (fiche 'Dugland 'Yvette)) = () 2.2.3 La Fonction type Nous introduisons une fonction ramenant en valeur le type au sens Ceyx de n'importe quel objet. (type <object>) Rame`ne en valeur le type de l'argument <object>, qui est e'value'. Cette fonction peut e↑tre de'finie en Lisp par: (de type (object) (cond ((null object) 'null) ((tconsp object) (car object)) 47 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types ((symbolp object) 'symbol) ((fixp object) 'fix) ((floatp object) 'float) ((stringp object) 'string) ((consp object) 'cons) ((vectorp object) 'vector)))) 2.3 La Construction send (send <msg> <obj> <arg>1 ... <arg>n) Tous les arguments sont e'value's. Cette construction recherche si le symbole <msg> existe et posse`de une de'finition de fonction dans l'espace de noms associe' a` (type <obj>) d'abord et dans ses parents ensuite, ceci jusqu'a` l'espace de nom racine || exclu. Si la recherche aboutit on applique cette fonction a` la liste d'arguments (<obj> <arg>1 ... <arg>n). Sinon on effectue la me↑me recherche dans l'espace de nom associe' au symbole * puis dans l'espace de nom racine et on continue comme pre'ce'demment en cas de re'ussite, sinon une erreur est de'clenche'e. En Le←Lisp, la construction send a e'te' introduite dans le noyau du langage pour les besoins de Ceyx. Dans d'autres syte`mes, elle peur e↑tre de'finie en Lisp par: (de send (msg args) (apply (#:Ceyx:getfn (type (car args)) msg) args)) (de #:Ceyx:getfn (package fun) (or (getfn package fun '||) (getfn '* fun))) 48 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types (sendq <msg> <obj> <arg>1 ... <arg>n) Cette construction est e'quivalente a` la pre'ce'dente, sinon qu'elle n'e'value pas son premier argument <msg>. Exemples ? (deftype Point (Field coord (Include Coord))) = Point ? (defmake Point mkpoint (x y)) = mkpoint ? (defaccess Point) = Point ? (setq p (Point 1 2)) ** eval : fonction indefinie : Point [stack 3] (lock ...) [stack 2] (tag #:system:error-tag ...) [stack 1] (itsoft ...) ? (setq p (mkpoint 1 2)) = #(Point 1 . 2) ? (send 'x p) = 1 ? (send 'y p 10) = (1 . 10) ? p = #(Point 1 . 10) ? (deftype Vector (Field vect (Include Vect))) = Vector ? (defaccess Vector) = Vector ? (defmake Vector mkvector (xorg yorg xext yext)) = mkvector ? (setq v (mkvector 0 0 10 25)) = #(Vector (0 . 0) 10 . 25) ? (de {Vector}:translate (vector dx dy) ? ({Vector}:xorg vector (+ dx ({Vector}:xorg vector))) ? ({Vector}:yorg vector (+ dy ({Vector}:yorg vector))) ? ({Vector}:xext vector (+ dx ({Vector}:xext vector))) ? ({Vector}:yext vector (+ dy ({Vector}:yext vector))) 49 Mercredi 3 Octobre 1984 Programmer en Ceyx 2: Les Types ? vector) = #:Vector:translate ? (sendq translate v 5 5) = #(Vector (5 . 5) 15 . 30) ? (de {fiche}:imprime (fiche) ? (print "Nom: " (sendq nom fiche)) ? (print "Prenom: " (sendq prenom fiche)) ? t) = #:fiche:imprime ? x = #(#:fiche:fiche-cordonnier (Jacquemart . Marcel) . #[Inconnue 48]) ? (sendq imprime x) Nom: Jacquemart Prenom: Marcel = t ? (de {fiche-cordonnier}:imprime (fiche) ? ({fiche}:imprime fiche) ? (print "Adresse: " (sendq adresse fiche)) ? (print "Pointure: " (sendq pointure fiche)) ? t) = #:fiche:fiche-cordonnier:imprime ? (sendq imprime x) Nom: Jacquemart Prenom: Marcel Adresse: Inconnue Pointure: 48 = t 50 Mercredi 3 Octobre 1984 Programmer en Ceyx 3: Le Pre'compilateur C H A P I T R E 3 Le Pre'compilateur ←B←e←r←t←r←a←n←d ←S←e←r←l←e←t 3.1 Objectifs Tous les programmes Ceyx sont compilables par le compilateur standard Le←Lisp, mais pour obtenir une efficacite' maximale lors de l'exe'cution il est pre'fe'rable de leur faire subir un pre'traitement. Ce pre'traitement se fait gra↑ce au compilateur Ceyx, appele' cxcp, conc,u comme une couche au dessus du compilateur Le←Lisp. Cxcp permet aussi le de'couplage avec le compilateur Le←Lisp, d'ou` une re'partition des ta↑ches. Ce pre'traitemant consiste actuellement: - a` compiler de fac,on spe'ciale les acce`s aux champs des objets Ceyx; - a` expanser a` la demande certaines fonctions comme s'il s'agissait de macros; - a` optimiser la compilation de certains send. 51 Mercredi 3 Octobre 1984 Programmer en Ceyx 3: Le Pre'compilateur 3.1.1 Compilation des acce`s aux champs Contrairement aux versions pre'ce'dentes de Ceyx, les fonctions d'acce`s aux champs sont maintenant de'finies comme des fonctions standards (par ←d←e) et non plus comme des macros. L'avantage e'norme de ce changement est d'autoriser l'utilisation de la construction send pour acce'der aux champs. Cela permet aussi de rendre la mise au point plus facile puisque l'on peut pister ou profiler (par ←t←r←a←c←e ou ←t←i←m←e←t←r←a←c←e) les appels. Il est aussi possible de faire dynamiquement des ve'rifications de type, lors de la mise au point, en modifiant la de'finition de ces fonctions. Malheureusement ces nouvelles possibilite's ont un prix: on perd un appel fonctionnel (en fait deux) et une construction de ←c←o←n←s a` chaque appel (car les fonctions d'acce`s ont un nombre variable d'arguments). Cette perte d'efficacite', supportable lors de la mise au point, est intole'rable en compile'. Cxcp remplace tous les appels explicites a` des fonctions d'acce`s par la chai↑ne d'acce`s elle-me↑me. Une fois le code compile', tout se passe donc comme dans les versions ante'rieures, et les programmes compile's restent aussi efficaces. : (defmodel test (Record (Field a) (Field b))) = test : (defaccess test) = test : (de testfun (x) (+ (#:test:a x) (#:test:b x)))) = testfun : (pretty #:test:a) (de #:test:a obj (#:Ceyx:system:g138 obj)) = () : (compile testfun () t) testfun se compile. (de testfun (x) (+ (#:test:a x) (#:test:b x))) ((fentry testfun subr1) (mov '(testfun x) a4) (call $cbind1) (mov nil a2) 52 Mercredi 3 Octobre 1984 Programmer en Ceyx 3: Le Pre'compilateur (call cons) (call #:test:a) (push a1) (mov (cvalq x) a1) (mov nil a2) (call cons) (call #:test:b) (mov a1 a2) (pop a1) (plus a2 a1) (return)) = ((2 . -12430)) : (de testfun (x) (+ (#:test:a x) (#:test:b x))) ** de : fonction redefinie : testfun = testfun : (cxcp testfun () t) testfun se compile. (de testfun (x) (+ (#:test:a x) (#:test:b x))) ((fentry testfun subr1) (mov '(testfun x) a4) (call $cbind1) (mov (car a1) a1) (mov (cvalq x) a2) (cdr a2) (plus a2 a1) (return)) = () 3.1.2 Expansion a` la demande de fonctions Il est parfois ne'cessaire pour des sections de programmes critiques en temps de transformer de petites fonctions en macros, afin d'y gagner un appel fonctionnel. La me'thode habituelle consiste a` e'crire d'abord la fonction sous forme de ←d←e, puis a` la saupoudrer de quelques caracte`res bizarres (` , ,. ,@ !). (de test (x y) (+ x y 1)) -> (dmd test (x y) `(+ ,x ,y 1)) 53 Mercredi 3 Octobre 1984 Programmer en Ceyx 3: Le Pre'compilateur ; ou, si l'on n'aime pas la backquote: (dmd test (x y) (list '+ x y 1)) Mais attention, la transformation en macro cache le pie`ge de double e'valuation des variables: (de test (x) (+ x x 1)) -> (dmd test (x) `(+ ,x ,x 1)) ; est faux, par exemple sur l'appel: (test (nextl l) (nextl l)) Dans cet exemple, une protection correcte en double e'valuation peut se faire par: (dmd test (x) (if (atomp x) `(+ ,x ,x 1) (let ((var (gensym))) `(let ((,var ,x)) (+ ,var ,var 1))))) Cxcp permet d'e'viter la transformation en macro a` la main. L'utilisateur choisit explicitement les fonctions expanse'es, et pre'cise, toujours explicitement, les variables a` prote'ger en double e'valuation. 3.1.3 Compilation des send Send est la fonction de base pour le style de programmation oriente' objet. Malheureusement cette fonction cou↑te cher, moins cher en Le←Lisp (ou` elle fait partie de l'interpre`te) que sur d'autres dialectes Lisp, mais elle est toujours plus cou↑teuse qu'un simple appel fonctionnel. Or il apparai↑t a` l'usage que pour bon nombre de se'mantiques, les appels a` send peuvent e↑tre optimise's en un ←s←e←l←e←c←t←q aiguillant suivant le type de l'objet sur un appel fonctionnel direct. Pour que cxcp sache quels sont les types d'objets les plus fre'quents, l'utilisateur fournit au compilateur une expression Lisp a` e'valuer, en comptant (conceptuellement) lors de cette phase d'e'valuation, la fre'quence des apparitions. Lors de la phase de compilation cxcp utilise cette information pour ge'ne'rer des selectq optimaux. 54 Mercredi 3 Octobre 1984 Programmer en Ceyx 3: Le Pre'compilateur 3.2 Utilisation du pre'-compilateur 3.2.1 Appel du Compilateur (cxcp) De me↑me que la fonction Le←Lisp compile-all-in-core, cette fonction compile toutes les fonctions de l'oblist en leur faisant pre'alablement subir les traitements propres a` cxcp. (cxcp <fun> [ind1 [ind2 [ind3]]]) (cxcp (<fun>1 ... <fun>k) [ind1 [ind2 [ind3]]]) Les <fun>i ne sont pas e'value'es. Compile une fonction ou une liste de fonctions en leur faisant subir pre'alablement les traitements propres a` cxcp. Les indicateurs optionnels ind1, ind2 et ind3 ont la me↑me signification que dans la fonction compiler du compilateur Le←Lisp. (cxcp-package <pckg> [ind1 [ind2 [ind3]]]) (cxcp-package (<pkg>1 ... <pkg>n) [ind1 [ind2 [ind3]]]) La me↑me chose que la pre'ce'dente sur toutes les fonctions d'un package ou d'une liste de packages. 55 Mercredi 3 Octobre 1984 Programmer en Ceyx 3: Le Pre'compilateur 3.3 Expansion a` la Demande L'expansion a` la demande de fonctions Lisp est re'alise'e par la construction cxcp-inline. (cxcp-inline <fundescr>1 ... <fundescr>n) Les <fundescri>, qui ne sont pas e'value's sont: - soit des noms de fonctions, - soit des listes (<fun> <arg>1 ... <argn>), ou` <fun> est un nom de fonction et les <arg>j le nom des arguments de <fun> qu'on veut prote'ger contre le phe'nome`ne de double e'valuation. Remarque: le compilateur refuse de transformer des fonctions a` nombre variable d'arguments en e'mettant un message d'avertissement. Attention: Aucune ve'rification n'est faite sur la validite' de l'expansion inline. Des cas triviaux ou` l'expansion inline simple peut ne pas e↑tre suffisante sont: - les cas de double e'valuation - les cas d'appels avec effets de bords. - les cas d'appel de FSUBR. Un exemple typique est la fonction xcons: (de xcons (a b) (cons b a)) Pour cette fonction, l'expansion inline est fausse si l'ordre des effets de bord des arguments d'appel importe. Un autre cas difficile: (de foo () (omakeq foo foo)) qui devrait engendrer: (dmd foo () `(omakeq foo ,foo)) 56 Mercredi 3 Octobre 1984 Programmer en Ceyx 3: Le Pre'compilateur Ce cas difficile est en fait re'solu par l'application du macro- expanseur avant tout traitement. 3.4 Expansion des send guide'e par une e'valuation La construction pre'sente'e dans cette partie est un premier pas vers la compilation personnalise'e de type "execute and compile", puisqu'elle est guide'e par une premie`re exe'cution sur le programme de l'utilisateur. (ecxcp <expr>) (ecxcp <expr> <fun> [ind1 [ind2 [ind3]]]) (ecxcp <expr> (<fun>1 ... <fun>k) [ind1 [ind2 [ind3]]]) Les <fun>i ne sont pas e'value's. Avant d'appeler la fonction cxcp standard, avec les <fun>i (non e'value's comme pour cxcp) et e'ventuellement les indicateurs, l'expression <expr> est e'value'e dans un environnement ou` tous les appels a` send dans les fonctions a` compiler sont dynamiquement e'tendus en des selectq sur tous les types des objets successifs auxquels ce send envoie des messages. La dernie`re clause du selectq est de la forme: (t (send ...)) Cet appel a` send garantit l'extensibilite'. De`s que le nombre de clauses de'passe la valeur de la variable #:cxcp:ecxcp, qui vaut 5 par de'faut, l'expansion est annule'e au profit d'un send classique. 57 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale C H A P I T R E 4 La Bibliothe`que Initiale ←J←e←a←n-←M←a←r←i←e ←H←u←l←l←o←t Nous pre'sentons dans ce chapitre un certain nombre de constructions qui ont e'te' de'clare'es d'utilite' publique au cours du temps. 4.1 Les Records Il s'agit ici de de'finir des mode`les qui sont des arbres binaires e'quilibre's de Cons dont les feuilles sont des Fields, a` partir de la liste de ces Fields. Pour cela, nous avons introduit un nouveau macromode`le de nom Record dans le langage de mode`les: (Record <model>1 ... <model>n) qui est interpre'te' comme un arbre binaire e'quilibre' de Cons: (Cons (Cons ... (Cons <model>1 <model>2) ...) (Cons ... (Cons <model>n-1 <model>n) ...)) Exemples ? (defmodel toto (Record (Field a) (Field b) (Field c) (Field d))) = toto ? ;est e'quivalent a` ? (defmodel toto (Cons (Cons (Field a) (Field b)) ? (Cons (Field c) (Field d)))) 58 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale = toto Nous donnons une construction permettant de de'finir des records avec une syntaxe alle'ge'e. Pour cela nous de'finissons d'abord ce qu'est un descripteur de champ <fielddescr>: <fielddescr> = <symbol> |<symbol>~<model> |(<symbol> <object>) |(<symbol>~<model> <object>) Dans le contexte des constructions defrecord, deftrecord, defclass et deftclass de'finies ci-apre`s, les <fielddescr> seront respectivement interpre'te's comme: (Field <symbol>) (Field <symbol> <model>) (Field <symbol> * <object>) (Field <symbol> <model> <object>) (defrecord <name> <fielddescr>1 ... <fielddescr>n) (defrecord (<name> <abbrev>) ...) Aucun argument n'est e'value'. Dans le cas ou <abbrev> n'est pas fourni, on le prend e'gal au pname de <name> dans le package global Le←Lisp ||. ←A←t←t←e←n←t←i←o←n, ←c←e←c←i ←n'←e←s←t ←p←a←s ←d←u ←t←o←u←t ←l←e ←c←a←s ←p←o←u←r ←l←a ←c←o←n←s←t←r←u←c←t←i←o←n ←d←e←f←m←o←d←e←l. Cette construction est e'quivalente a`: (defmodel (<name> <abbrev>) (Record <fielddescr>1 ... <fielddescr>n)) (defaccess <name>) Exemples ? (defrecord toto a (b~string "") c~fix) = toto ? (defmake toto toto (a b c)) = toto 59 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale ? (setq x (toto 1 "ahlala" 3)) = (1 "ahlala" . 3) ? ({toto}:a x) = 1 ? ; mais attention a` l'exportation par de'faut dans || ? (defrecord #:toto:tata a b c) = #:toto:tata ? '{tata} = #:toto:tata ? (defrecord Coord (x~fix 0) (y~fix 0)) = Coord ? (defmake Coord Coord (x y)) = Coord (deftrecord <name> <fielddescr>1 ... <fielddescr>n) (deftrecord (<name> <abbrev>) ...) Cette construction est e'quivalente a` la pre'ce'dente, sinon qu'on engendre un type au lieu d'engendrer un mode`le. Exemples ? (deftrecord Point coord~(Include Coord))) = Point ? (defmake Point mkpoint (x y)) = mkpoint ? (defmake Point Point coord) = Point ? (mkpoint 1 2) = #(Point 1 . 2) ? (Point (Coord 1 2)) = #(Point (1 . 2)) 60 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale 4.2 Les Classes Il s'agit ici de donner des facilite's pour de'crire des mode`les toujours extensibles: on les de'finit comme des Vectors de mode`les qui sont donc toujours extensibles par la droite. Ces mode`les sont appele's des classes et, pour eux, la hie'rarchie structurelle coincide avec la hie'rarchie des espaces se'mantiques. En effet, le nom d'une sous-classe est toujours interne' dans l'espace de noms de la classe me`re. Pour de'finir les classes, nous commenc,ons par de'finir une classe initiale: ? (defmodel Class (Field class-attributes (Vector))) = Class et pour les classes qui sont des types, une Tclasse initiale: ? (deftype Tclass (Field class-attributes (Vector))) = Tclass Le principe de la construction des classes consiste a` e'tendre re'pe'titivement ces classes au champ class-attributes. Ceci est re'alise' par les constructions defclass et deftclass. (defclass <name> <fielddescr>1 ... <fielddescr>n) (defclass (<name> <abbrev>) ...) Aucun argument n'est e'value'. Dans le cas ou <abbrev> n'est pas fourni, on prend pour abbre'viation de <name> le symbole du package global || Le←Lisp dont le pname est ||. ←A←t←t←e←n←t←i←o←n, ←c←e←c←i ←n'←e←s←t ←p←a←s ←d←u ←t←o←u←t ←l←e ←c←a←s ←p←o←u←r ←l←a ←c←o←n←s←t←r←u←c←t←i←o←n ←d←e←f←m←o←d←e←l. Le symbole <name> doit avoir pour packagecell un symbole <supername> qui posse`de une de'finition de classe. Cette construction est alors e'quivalente a`: (defmodel (<name> <abbrev>) (Extend <supername> 61 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale class-attributes (Vector <fielddescr>1 ... <fielddescr>n)) (defaccess <name> <fieldname>1 ... <fieldname>i) ←A←t←t←e←n←t←i←o←n ←q←u←e ←p←o←u←r ←l←e←s ←c←l←a←s←s←e←s, ←l←e ←d←e←f←a←c←c←e←s←s ←n'←e←s←t ←f←a←i←t ←q←u←e ←s←u←r ←l←e←s ←n←o←u←v←e←a←u←x ←c←h←a←m←p←s. (deftclass <name> <fielddescr>1 ... <fielddescr>n) (deftclass (<name> <abbrev>) ...) Cette construction est e'quivalente a` la pre'ce'dente, sinon qu'on engendre un type au lieu d'engendrer un mode`le et uqe les Tclasses sont des extensions de la Tclasse initiale Tclass. Exemples ? (deftclass fiche nom prenom) = #:Tclass:fiche ? (defmake {fiche} fiche (nom prenom)) = fiche ? (setq fiche (fiche 'Jacquemart 'Marcel)) = #(#:Tclass:fiche . #[Jacquemart Marcel]) ? (deftclass {fiche}:fiche-client adresse~string) = #:Tclass:fiche:fiche-client ? (deftclass {fiche-client}:fiche-cordonnier pointure~fix) = #:Tclass:fiche:fiche-client:fiche-cordonnier ? (defmake {fiche-cordonnier} fiche-cordonnier ? (nom prenom adresse pointure)) = fiche-cordonnier ? (setq fiche (fiche-cordonnier 'Jacquemart ? 'Marcel ? "Inconnue" ? 48)) = #(#:Tclass:fiche:fiche-client:fiche-cordonnier . #[Jacquemart Marcel Inconnue 48]) ? ; sacre'e pointure! ? (deftclass {fiche}:fiche-police condamnations~string) = #:Tclass:fiche:fiche-police 62 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale ? (defmake {fiche-police} fiche-police (nom prenom condamnations)) = fiche-police ? (fiche-police 'Jacquemart 'Marcel "Vol de Chaussures") = #(#:Tclass:fiche:fiche-police . #[Jacquemart Marcel Vol de Chaussures]) ? ; pour une fois qu'il en avait trouve' a` sa taille! 4.3 Les Arbres Les arbres sont des types construits a` partir d'un type arbre initial: (deftype Tree (Cons (Field sons) (Field tree-attributes (Vector)))) Par un principe tout a` fait analogue a` celui utilise' pour les classes, les extensions successives se font en e'tendant le Vector du champ tree-attributes. Ceci est re'alise' par la construction deftree: (deftree <name> <fielddescr>1 ... <fielddescrn>) (deftree (<name> <abbrev>)) <fielddescr>1 ,,, <fielddescr>n) Cette contruction est analogue a` deftclass sinon qu'on e'tend a` partir du type Tree au lieu du type Tclass. La nouveaute' des arbres par rapport aux classes re'side dans la possibilite' de de'finir des "constructeurs", par exemple les ope'rateurs du langage quand on utilise les arbres pour construire la syntaxe abstraite d'un langage de programmation. Il s'agit donc, e'tant donne' un arbre posse'dant un certains nombres d'attributs, de spe'cifier comment sont structure's ses fils. 63 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale (defcons <name> <sonsdescr> <fielddescr>1 ... <fielddescr>n) (defcons (<name> <abbrev>) <sonsdescr> ...) Comme pour les classes et les arbres, <name> est un symbole dont le packagecell <supername> doit avoir une de'finition d'arbre et <abbrev> s'il est omis est pris e'gal a` (symbol '|| <name>). Les <fielddescr>i sont interpre'te's comme pour le deftree, i.e. ce sont des champs qui sont ajoute's en queue de tree-attributes. <sonsdescr> est soit un fielddescr auquel cas le champ sons a pour mode`le <fielddescr>, soit une liste de <fielddescr> auquel cas le champ sons a pour mode`le le Vector contruit a` partir de cette liste. De plus une fontion de nom <abbrev> de cre'ation du type est engendre'e prenant un nombre variable d'argument dans le cas ou <sonsdescr> est un <fielddescr> et un nombre d'arguments e'gal a` la longueur de <fielddescr> autrement. Ces arguments permettent de construire le champ sons des instances (voir exemples). Enfin un defaccess est fait sur tous les nouveaux champs et tous les champs spe'ciaux que sont les fils. Exemples Nous pre'sentons en exemple l'imple'mentation d'une syntaxe abstraite pour un sous ensemble du langage de description de transparents Flip de G. Kahn. Il s'agit d'un petit langage ge'ome'trique permettant de de'couper le plan en bandes horizontales (l'ope'rateur horiz a` nombre variable d'arguments), en bandes verticales (l'ope'rateur vertic a` nombre variable d'arguments), en re'gions rectangulaires atomiques contenant du texte (l'ope'rateur aligner a` nombre variable de chai↑nes de caracte`res arguments) et en re'gions rectangulaires atomiques contenant une diagonale d'une certaine couleur (l'ope'rateur diag a` un argument, sa couleur). Chaque bande ou re'gion posse`de une proportion qui permet de calculer sa taille propre dans sa bande me`re, elle peut e↑tre encadre'e d'une certaine couleur, peinte d'une certaine couleur, le texte peut y e↑tre e'crit d'une certaine couleur. Tous ces attributs communs a` tous les objets Flip, seront 64 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale stocke'es dans une structure Flip de'finie par: ? (deftree Flip ? (proportion~fix 1) ? cadre ? texte ? peinture = #:Tree:Flip Nous de'finissons les diffe'rents ope'rateurs du langage: ? (defcons {Flip}:horiz sons~(List Flip)) = #:Tree:Flip:horiz ? (defcons {Flip}:vertic sons~(List Flip)) = #:Tree:Flip:vertic ? (defcons {Flip}:aligner sons~(List string)) = #:Tree:Flip:aligner ? (defcons {Flip}:diag (color~color)) = #:Tree:Flip:diag et nous illustrons par des exemples les diverses fonctions engendre'es: ? (setq flip (diag 'rouge)) = #(#:Tree:Flip:diag #[rouge] . #[1 () () ()]) ? ({Tree}:sons flip) = #[rouge] ? ({diag}:color flip) = rouge ? ({diag}:sons flip) ** eval : fonction indefinie : #:Tree:Flip:diag:sons [stack 3] (lock ...) [stack 2] (tag #:system:error-tag ...) [stack 1] (itsoft ...) ? (setq flip (aligner "toto" "tutu" "titi")) = #(#:Tree:Flip:aligner (toto tutu titi) . #[1 () () ()]) ? ({aligner}:sons flip) 65 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale = (toto tutu titi) ? (setq flip (horiz (diag 'vert) (diag 'bleu))) = #(#:Tree:Flip:horiz (#(#:Tree:Flip:diag #[vert] . #[1 () () ()]) #(#:Tree: Flip:diag #[bleu] . #[1 () () ()])) . #[1 () () ()]) ? (sendq proportion flip) = 1 ? ({Flip}:cadre flip 'bleu) = bleu ? (sendq cadre flip) = bleu L'imple'mentation comple`te de Flip est donne'e en Annexe IV. 4.4 Les Re`gles Nous avons vu comment la construction send donne un ro↑le tout particulier a` son premier argument, puisque c'est sur lui qu'est fait le de'codage de type permettant de trouver la fonction qu'il faut appliquer. Parfois il serait agre'able de pouvoir faire la recherche de la fonction a` appliquer en profitant des informations de types sur plusieurs arguments. Ceyx propose une constrution permettant de le faire dans le cas de deux arguments, elle sera e'tendue ulte'rieurement au cas de n arguments type's. Nous expliquons cette construction sur un exemple. Nous voulons de'finir une ope'ration d'addition sur les re'els et les complexes. Pour cela, nous de'finissons tout d'abord les types Reel et Complexe: ? (deftype Reel (Field val number 0)) = Reel ? (defmake Reel reel (val)) = reel ? (defaccess Reel) = Reel ? (deftype Complexe (Cons (Field reelle number 0) ? (Field imaginaire number 0))) 66 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale = Complexe ? (defmake Complexe complexe (reelle imaginaire)) = complexe ? (defaccess Complexe) = Complexe Il nous est assez difficile d'exprimer en Ceyx une loi d'addition sans de'finir une se'mantique + sur chacun des deux types envoyant des se'mantiques relais +reel ou +complexe a` la liste d'arguments renverse'e. Le but de la construction defrule est de vous e'viter toute cette salade. Ce qu'il faut savoir, c'est qu'au moment du send la recherche de la fonction a` appliquer sera faite en tenant compte des types des deux premiers arguments en ordre lexicographique pour la remonte'e hie'rarchique. Dans le cas de type A2 <=p A1 pour le premier argument et B2 <=p B1 pour le deuxie`me argument, nous inspecterons donc successivement A2xB2, A2xB1, A1xB2, A1xB1. ? (defrule + (x~Reel y~Reel) ? (reel (+ ({Reel}:val x) ({Reel}:val y)))) = + ? (sendq + (reel 1) (reel 2))) = #(Reel . 3) ? (sendq + (reel 1) (complexe 2 3)) ** + : l'argument n'est pas un nombre : #(Complexe 2 . 3) [stack 4] (#:Reel:+ ...) [stack 3] (lock ...) [stack 2] (tag #:system:error-tag ...) [stack 1] (itsoft ...) ? ; et oui puisqu'on ne trouve pas de cas ReelxComplexe, on remonte ? ; jusqu'au package global, ou on trouve la fonction Lisp + ? ; classique, qui provoque l'erreur puisque le type de l'argument ? ; n'est pas le bon. ? (defrule + (x~Reel y~Complexe) ? (complexe (+ ({Reel}:val x) ({Complexe}:reelle y)) ? ({Complexe}:imaginaire y))) = + ? ; et cette fois-ci on peut faire ? (sendq + (reel 1) (complexe 2 3)) 67 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale = #(Complexe 3 . 3) ? (defrule + (x~Complexe y~Complexe) ? (complexe (+ ({Complexe}:reelle x) ({Complexe}:reelle y)) ? (+ ({Complexe}:imaginaire x) ? ({Complexe}:imaginaire y)))) = + ? (sendq + (complexe 1 2) (complexe 3 4)) = #(Complexe 4 . 6) (defrule <name> (<arg>1~<type>1 <arg>2~<type>2 . <args>) . <body>) De'finit la re`gle de nom name sur le produit carte'sien <type>1x<type>2. On notera qu'un re`gle prend donc deux arguments type's et autant d'arguments Lisp standards qu'on le de'sire. (undefrule <name>) Enle`ve toute trace de la re`gle de nom <name>. Apre`s cette ope'ration la re`gle <name> n'existe litte'ralement plus. 4.5 De'structuration Il s'agit de constructions permettant de de'structurer automatiquement un objet dans les variables locales d'un let. (olet (<modelname> <dfields> <obj>) . <body>) <dfields>= (<dfield>1 ... <dfield>n) ou <dfield> est soit un nom de champ de <modelname>, soit une liste (<fieldname>i <symbol>i). Cette construction se macroge'ne`re en (let (<exp>1 ... <expn>) . <body>)) ou` <exp>i = (<fieldname>i (ogetq <modelname> <fieldname>i <object>)) ou 68 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale <exp>i = (<symbol>i (ogetq <modelname> <fieldname>i <object>)). Exemples: ? (defmake toto toto (a b c)) = toto ? (olet (toto (a c) (toto 1 2 3)) (print a) (print c)))) 1 3 = 3 2 3 = 3 (demethod <name> (<obj> . <args>) <dfields> . <body>) Cette construction permet de de'structurer des champs se'lectionne's de son premier argument <obj> dans des variables locales de la fonction. Elle est e'quivalente a`: (de <name> <args> (olet ((packagecell <name>) <dfields> <obj>) . <body>)) Exemples ? (demethod {toto}:print (x) (a b c) ? (print "a: " a) ? (print "b: " b) ? (print "c: " c) ? t) = #:toto:print ? (pretty #:toto:print) (de #:toto:print (x) (olet (toto (a b c) x) (print "a: " a) (print "b: " b) (print "c: " c) t)) = () 69 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale (unde <name>) Enle`ve la de'finition de fonction du symbole <name>. 4.6 O..Q (ochangeq <modelname> <object> <field>1 <val>1 ... <field>n <val>n) <modelname> et les <field>i qui doivent e↑tre des noms de champs ne sont pas e'value's, <object> doit e↑tre une instance de <modelname>, ses champs <field>i prennent les valeurs <val>i et <object> est ramene' en valeur. (ofunq <modelname> <field> <object> <fun> . <args>) <modelname> et <field> et <fun> ne sont pas e'value's, <object> doit e↑tre une instance de <modelname>, son champ field est remplace, par (apply <fun> (cons (ogetq <modelname> <field> <object>) <args>)) Un cas particulier: (oconsq <modelname> <field> <object> <val>) <modelname> et <field> ne sont pas e'value's, <object> doit e↑tre une instance de <modelname>, son champ <field> est remplace' par (cons <val> (ogetq <modelname> <field> <object>)) Cette construction peut e↑tre de'finie en Lisp par: (defmacro oconsq (model field obj val) 70 Mercredi 3 Octobre 1984 Programmer en Ceyx 4: La Bibliothe`que Initiale `(ofunq ,model ,field ,obj xcons ,val)) Exemples ? (setq x (tata 1 2)) = #(tata 1 . 2) ? (ochangeq tata x a () b 0) = #(tata () . 0) ? (ofunq tata b x + 1) = #(tata () . 1) ? (oconsq tata a x 'aa) = #(tata (aa) . 1) ? (oconsq tata a x 'bb) = #(tata (bb aa) . 1) 4.7 Me'canisme de Trace (tracesems <msg>1 ... <msg>n) Les arguments ne sont pas e'value's. Permet de tracer au sens Lisp, toutes les proprie'te's se'mantiques de pname <msg>1, ..., <msg>n. 71 Mercredi 3 Octobre 1984 Table des matie`res 1 Mercredi 3 Octobre 1984 Table des matie`res Table des matie`res 1 Les Mode`les 1.1 Introduction.........................................9 1.2 Le Langage de Description de Mode`les................11 1.2.1 Syntaxe...........................................11 1.2.2 Se'mantique........................................13 1.2.2.1 Discrimination..................................13 1.2.2.2 De'structuration.................................16 1.2.2.3 Instantiation...................................18 1.2.3 Les Macro Mode`les.................................21 1.3 De'finition de Mode`les...............................24 1.3.1 La Construction defmodel..........................24 1.3.2 La Construction defaccess.........................25 1.3.3 La Construction defmake...........................26 1.3.4 Les Mode`les Pre'de'finis............................28 1.4 Les Espaces Se'mantiques.............................29 1.4.1 Les Espaces de Noms...............................29 1.4.2 Les Proprie'te's Se'mantiques des Mode`les............32 1.4.3 Re'cupe'ration Fonctionnelle Hie'rarchique...........34 1.5 Description de Mode`les..............................36 2 Les Types 2.1 Les Types Lisp......................................43 2.2 Les Types Ceyx......................................44 2.2.1 Les Objets........................................44 2.2.2 La Contruction deftype............................45 2.2.3 La Fonction type..................................47 2.3 La Construction send................................48 3 Le Pre'compilateur 3.1 Objectifs...........................................51 3.1.1 Compilation des acce`s aux champs..................52 3.1.2 Expansion a` la demande de fonctions...............53 3.1.3 Compilation des send..............................54 3.2 Utilisation du pre'-compilateur......................55 3.2.1 Appel du Compilateur..............................55 3.3 Expansion a` la Demande..............................56 3.4 Expansion des send guide'e par une e'valuation........57 2 Mercredi 3 Octobre 1984 Table des matie`res 4 La Bibliothe`que Initiale 4.1 Les Records.........................................58 4.2 Les Classes.........................................61 4.3 Les Arbres..........................................63 4.4 Les Re`gles..........................................66 4.5 De'structuration.....................................68 4.6 O..Q................................................70 4.7 Me'canisme de Trace..................................71 3 Mercredi 3 Octobre 1984 Index des fonctions Lisp 1 Mercredi 3 Octobre 1984 Index des fonctions Lisp Index des fonctions Lisp (<=p <symbol>1 <symbol>2) ..............................29 (apropos <package>) ....................................37 (cxcp (<fun>1 ... <fun>k) [ind1 [ind2 [ind3]]]) ........55 (cxcp <fun> [ind1 [ind2 [ind3]]]) ......................55 (cxcp) .................................................55 (cxcp-inline <fundescr>1 ... <fundescr>n) ..............56 (cxcp-package (<pkg>1 ... <pkg>n) [ind1 [ind2 [ind3]]]) 55 (cxcp-package <pckg> [ind1 [ind2 [ind3]]]) .............55 (defabbrev <full-name> <abbrev>) .......................30 (defaccess <modelname> <fieldname>1 ... <fieldname>n) ..25 (defclass (<name> <abbrev>) ...) .......................61 (defclass <name> <fielddescr>1 ... <fielddescr>n) ......61 (defcons (<name> <abbrev>) <sonsdescr> ...) ............64 (defcons <name> <sonsdescr> <fielddescr>1 ... <fielddescr>n) 64 (defmake <modelname> <mkname> (<fieldname>1 ... <fieldname>n)) 26 (defmake <modelname> <mkname>) .........................26 (defmodel (<name> <abbrev>) <model>) ...................31 (defmodel <name> <model>) ..............................24 (defrecord (<name> <abbrev>) ...) ......................59 (defrecord <name> <fielddescr>1 ... <fielddescr>n) .....59 (defrule <name> (<arg>1~<type>1 <arg>2~<type>2 . <args>) . <body>) 68 (deftclass (<name> <abbrev>) ...) ......................62 (deftclass <name> <fielddescr>1 ... <fielddescr>n) .....62 (deftrecord (<name> <abbrev>) ...) .....................60 (deftrecord <name> <fielddescr>1 ... <fielddescr>n) ....60 (deftree (<name> <abbrev>)) <fielddescr>1 ,,, <fielddescr>n) 63 (deftree <name> <fielddescr>1 ... <fielddescrn>) .......63 (deftype (<name> <abbrev>) <model>) ....................46 (deftype <name> <model>) ...............................46 (demethod <name> (<obj> . <args>) <dfields> . <body>) ..69 (describe <object> [<modelname>]) ......................37 (ecxcp <expr> (<fun>1 ... <fun>k) [ind1 [ind2 [ind3]]]) 57 (ecxcp <expr> <fun> [ind1 [ind2 [ind3]]]) ..............57 (ecxcp <expr>) .........................................57 (getfn <pkg> <sym> <lastpkg>) ..........................35 (getfn <pkg> <sym>) ....................................35 (hfuncall <pkg> <sym> <arg>1 ... <arg>n) ...............35 2 Mercredi 3 Octobre 1984 Index des fonctions Lisp (mdescribe <modelname> [<prof>]) .......................36 (ochangeq <modelname> <object> <field>1 <val>1 ... <field>n <val>n) 70 (oconsq <modelname> <field> <object> <val>) ............70 (ofunq <modelname> <field> <object> <fun> . <args>) ....70 (ogetq <modelname> <fieldname> <sexpr>) ................17 (olet (<modelname> <dfields> <obj>) . <body>) ..........68 (omake <modelname>) ....................................20 (omakeq <modelname> <fieldname>1 <sexpr>1 ... <fieldname>n <sexpr>n) 20 (omatchq <modelname> <sexpr>) ..........................15 (oputq <modelname> <fieldname> <sexpr> <val>) ..........17 (plink <abbrev>) .......................................30 (semcall <pkg> <sym> <arg>1 ... <arg>n) ................36 (send <msg> <obj> <arg>1 ... <arg>n) ...................48 (sendq <msg> <obj> <arg>1 ... <arg>n) ..................49 (tbl-describe <modelname>) .............................36 (tcons <symbol> <sexpr>) ...............................44 (tconsp <obj>) .........................................45 (tracesems <msg>1 ... <msg>n) ..........................71 (type <object>) ........................................47 (unde <name>) ..........................................70 (undefrule <name>) .....................................68 ({Ceyx}:getfn <pkg> <sym>) .............................35 3 Mercredi 3 Octobre 1984