L'exemple peut être vu selon deux jours :
Le langage cible est le langage Lisp.
On veut définir la fonction sqrt qui calcule la racine carrée d'un entier par la méthode classique : on construit une suite (an) telle que :
an+1 = 1/2 ( an + N/an )
(qui calcule la racine carrée de N).
On utilise d'abord le schéma des fonctions Lisp, le texte programme :
(def programme ()
("(de {NOM} ({PARAM})
{CORPS})"))
programme est paramétré par :
NOM : le nom de la fonction,PARAM : le paramètre de la fonction,CORPS : le corps de la fonction.
Pour construire son programme, on définit donc un nouveau texte, PGME, qui utilise le schéma prédéfini de déclaration d'une fonction programme. On donne dans la suite pour les premières étapes de construction les deux formes :
- textuelle : les textes qu'on définit ;
- visuelle : ce qu'on voit (à l'écran).
La construction
| forme textuelle | forme visuelle |
| |
On définit localement dans le texte construit | |
| |
|
On développe ensuite le corps en utilisant le schéma prédéfini d'itération par approximations successives
-
INITIALISATION : la valeur d'initialisation du résultat,- TEST : la tolérance du calcul,- APPROXIMATION : le calcul d'approximation.
| |
| |
On développe ensuite dans le corps chaque paramètre :
(1) INITIALISATION : égale 1
(2) TEST : on utilise « l'égalité à epsilon près » :
(def egal-epsilon ()
("(< (abs (- {ARG1} {ARG2})) {EPSILON})"))
ARG1 = "(* result result)"ARG2 = "num"EPSILON = "0.001"On construit donc le texte :
(def TEST
((def ARG1 () ("(* result result)"))
(def ARG2 () ("num"))
(def EPSILON () ("0.001")))
("{egal-epsilon}"))
qui donne :
(< (abs (- (* result result) num)) 0.001)
(3) APPROXIMATION : on utilise le schéma de la moyenne :
(def moyenne ()
("(/ (+ {ARG1} {ARG2}) 2)"))
ARG1 = "result"ARG2 = "(/ num result)"On construit alors :
(def APPROXIMATION
((def ARG1 () ("result"))
(def ARG2 () ("(/ num result)")))
("{moyenne}"))
qui donne :
(/ (+ result (/ num result)) 2)
On donne à la fin du paragraphe une vue synthétique de la bibliothèque des unités prédéfinies et du programme construit.
Conclusion
La construction progressive présente deux avantages :
Dans une démarche descendante, elle facilite l'écriture du programme. L'utilisateur en effet n'a pas à « réinventer la science » chaque fois qu'il écrit un programme : il réutilise un élément prédéfini de la bibliothèque. On gagne donc sur le plan de l'effort de développement demandé au programmeur ; on gagne surtout en fiabilité du programme – les éléments prédéfinis peuvent avoir été dûment validés, alors que le programme construit ne le sera vraisemblablement pas. Par exemple, si l'on regarde le texte succ-approx d'approximation successive :
Dans une démarche ascendante, elle facilite la relecture du programme. Si l'on s'éloigne de la « situation idéale » présentée précédemment où tous les besoins exprimés sont satisfaits dans la bibliothèque, on peut néanmoins offrir à l'utilisateur la possibilité de se replacer dans cette situation. Il s'agira alors pour lui :
Si l'utilisateur est placé dans un "environnement nu" – sans bibliothèque prédéfinie – son programme n'est alors pas « le fichier de texte fic.ll » qui contient la totalité de l'information mais une collection structurée de « textes » qu'il utilise simultanément. L'intérêt d'une telle approche est de permettre à l'utilisateur d'écrire son programme (il n'est pas arrêté dans l'affinage du programme parce que telle unité serait introuvable dans la bibliothèque) tout en lui donnant le moyen d'exprimer, dans le texte source, sa démarche de conception d'une solution.
La bibliothèque
(def programme ()
("(de {NOM} ({PARAM})
{CORPS})"))
(def succ-aprox ()
("(prog (result)
(setq result {INITIALISATION})
LP (cond ({TEST} (return result)))
(setq result {APPROXIMATION})
(go LP)))"))
(def egal-epsilon ()
("(< (abs (- {ARG1} {ARG2})) {EPSILON})"))
(def moyenne ()
("(/ (+ {ARG1} {ARG2}) 2)"))
La forme « textuelle » du programme
(def PGME
((def NOM () ("sqrt"))
(def PARAM () ("num"))
(def CORPS
((def INITIALISATION () ("1"))
(def TEST
((def ARG1 () ("(* result result)"))
(def ARG2 () ("num"))
(def EPSILON () ("0.001")))
("{egal-epsilon}"))
(def APPROXIMATION
((def ARG1 () ("result"))
(def ARG2 () ("(/ num result)")))
("{moyenne}")))
("{succ-approx}")))
("{programme}"))
La forme « visuelle » du programme
(de sqrt (num)
(prog (result)
(setq result 1)
LP (cond ((< (abs (- (* result result) num)) 0.001) (return result)))
(setq result (/ (+ result (/ num result)) 2))
(go LP)))