“doc” (Col. : Science Sup 17x24) — 2007/7/19 — 18:18 — page 209 — #219
i
i
i
i
i
i
i
i
4.4 Les principales limitations de la programmation déclarative
209
être obtenu sans aucun calcul. L’ajout d’une telle mémoire cache à une fonction
n’est pas modulaire parce qu’un accumulateur doit être enfilé à l’extérieur de la
fonction. L’accumulateur contient le contenu actuel de la mémoire cache.
2. Le deuxième exemple est l’instrumentation d’un programme. Nous voulons
savoir combien de fois certains sous-composants sont appelés. Nous voulons
ajouter des compteurs à ces sous-composants, de préférence sans changer leurs
interfaces ou le reste du programme. Si le programme est déclaratif, c’est impossible car la seule solution est d’enfiler des accumulateurs dans toutes les procédures qui appellent les sous-composants.
Regardons de plus près le deuxième exemple pour comprendre exactement pourquoi
le modèle déclaratif est insuffisant. Supposons que nous utilisons le modèle déclaratif
pour implémenter un grand composant. Voici la définition du composant :
fun {SC ...}
proc {P1 ...} ... end
proc {P2 ...} ... {P1 ...} {P2 ...} end
proc {P3 ...} ... {P2 ...} {P3 ...} end
in ´export´(p1:P1 p2:P2 p3:P3) end
Un appel de SC instancie le composant : il renvoie un module avec trois opérations,
P1, P2 et P3. Nous voulons instrumenter le composant pour compter le nombre
d’appels de la procédure P1. Les valeurs successives du compte forment un état. Nous
pouvons coder cet état comme un accumulateur, en ajoutant deux arguments à chaque
procédure. Avec cette instrumentation, la définition du composant ressemblerait à
ceci :
fun {SC ...}
proc {P1 ... S1 ?Sn} Sn=S1+1 ... end
proc {P2 ... T1 ?Tn} ...
{P1 ... T1 T2} {P2 ... T2 Tn} end
proc {P3 ... U1 ?Un} ...
{P2 ... U1 U2} {P3 ... U2 Un} end
in ´export´(p1:P1 p2:P2 p3:P3) end
Chaque procédure définie par SC a une nouvelle interface avec deux arguments supplémentaires. La procédure P1 est appelée comme {P1 ... Sin Sout}, où Sin est
le compte à l’entrée et Sout est le compte à la sortie. L’accumulateur doit être enfilé
entre les appels des procédures. Le module SC et le module qui l’appelle doivent tous
les deux faire ce travail administratif.
Une autre solution est d’écrire SC dans un modèle avec état. Un tel modèle est défini
dans le chapitre 5 ; pour le moment supposons que nous avons une nouvelle entité
du langage, appelée « cellule », que nous pouvons lire et écrire (avec les opérateurs
© Dunod – La photocopie non autorisée est un délit
i
i
i
i
i
i
i
i
4.4 Les principales limitations de la programmation déclarative
209
être obtenu sans aucun calcul. L’ajout d’une telle mémoire cache à une fonction
n’est pas modulaire parce qu’un accumulateur doit être enfilé à l’extérieur de la
fonction. L’accumulateur contient le contenu actuel de la mémoire cache.
2. Le deuxième exemple est l’instrumentation d’un programme. Nous voulons
savoir combien de fois certains sous-composants sont appelés. Nous voulons
ajouter des compteurs à ces sous-composants, de préférence sans changer leurs
interfaces ou le reste du programme. Si le programme est déclaratif, c’est impossible car la seule solution est d’enfiler des accumulateurs dans toutes les procédures qui appellent les sous-composants.
Regardons de plus près le deuxième exemple pour comprendre exactement pourquoi
le modèle déclaratif est insuffisant. Supposons que nous utilisons le modèle déclaratif
pour implémenter un grand composant. Voici la définition du composant :
fun {SC ...}
proc {P1 ...} ... end
proc {P2 ...} ... {P1 ...} {P2 ...} end
proc {P3 ...} ... {P2 ...} {P3 ...} end
in ´export´(p1:P1 p2:P2 p3:P3) end
Un appel de SC instancie le composant : il renvoie un module avec trois opérations,
P1, P2 et P3. Nous voulons instrumenter le composant pour compter le nombre
d’appels de la procédure P1. Les valeurs successives du compte forment un état. Nous
pouvons coder cet état comme un accumulateur, en ajoutant deux arguments à chaque
procédure. Avec cette instrumentation, la définition du composant ressemblerait à
ceci :
fun {SC ...}
proc {P1 ... S1 ?Sn} Sn=S1+1 ... end
proc {P2 ... T1 ?Tn} ...
{P1 ... T1 T2} {P2 ... T2 Tn} end
proc {P3 ... U1 ?Un} ...
{P2 ... U1 U2} {P3 ... U2 Un} end
in ´export´(p1:P1 p2:P2 p3:P3) end
Chaque procédure définie par SC a une nouvelle interface avec deux arguments supplémentaires. La procédure P1 est appelée comme {P1 ... Sin Sout}, où Sin est
le compte à l’entrée et Sout est le compte à la sortie. L’accumulateur doit être enfilé
entre les appels des procédures. Le module SC et le module qui l’appelle doivent tous
les deux faire ce travail administratif.
Une autre solution est d’écrire SC dans un modèle avec état. Un tel modèle est défini
dans le chapitre 5 ; pour le moment supposons que nous avons une nouvelle entité
du langage, appelée « cellule », que nous pouvons lire et écrire (avec les opérateurs
© Dunod – La photocopie non autorisée est un délit
