afficher >><< masquer ]
SAMPI - Editeur structuré
1. Le Problème et la Proposition
2. Le Langage Primitif de Représentation Textuelle
2.1. Présentation de la Syntaxe Concrète
2.2. Notations
2.3. Exemple de structuration des données
2.4. Exemple de structuration des traitements
2.5. Exemple de structurations connexes
2.5.1. Présentation
2.5.2. La macro-génération
2.5.22.1. Les données
2.5.22.2. Les traitements
2.5.3. Les symétries du programme
2.5.4. Annexe 1 : Construction du champ CHP_PRESENT
2.5.5. Annexe 2 : Les fonctions de traitement en Lisp
3. Le Langage Complété pour la Structuration des Textes
3.1. Présentation de la Syntaxe Complétée
3.2. Etude quantitative de l'évolution des programmes
3.3. L'édition syntaxique
3.4. étude de cas : le langage LTR3 et l'atelier ENTREPRISE
4. L'Enrichissement du Langage par de Nouveaux Concepts
4.1. Présentation de la Syntaxe Abstraite
4.2. Les difficultés
4.3. Compléter la Syntaxe
5. La Formalisation des Solutions Techniques
5.1. L'évaluation fonctionnelle
5.2. La structuration par les objets
5.3. Modèle sémantique comparé de l'évaluateur
5.4. Comparaison critique
5.5. Construction de la Syntaxe Abstraite
6. Les Comparaisons avec d'autres Approches
7. Les Perspectives
8. Les Editeurs
8.0. brisé sur la barrière de la complexité (une fois de plus)
8.1. L'éditeur ligne : Manuel de l'utilisateur
8.2. L'éditeur page : Guide de l'utilisateur
9. Les Aspects d'Implantation
9.1. Contexte d'évaluation
9.2. La Syntaxe Abstraite : Manuel du concepteur
9.3. L'éditeur page : Guide de l'implanteur
Références
Rubrique Perl-Javascript

La macro-génération

La macro-génération est une technique « vieille comme le monde », à la fois largement utilisée et largement critiquée. On l'utilise dans deux optiques :

Le gros avantage de la macro-génération en est sa simplicité. Mais cette simplicité ne doit pas masquer certains dangers qui lui sont liés :

On trouve dans [KoW 87] une syntaxe pour les macro-définitions en Lisp qui cherche à en faciliter la compréhension : au lieu de proposer classiquement une fonction qui permette de tester sur quelques exemples la macro-génération, on propose un moyen d'expression qui fait ressembler la macro-définition à sa forme macro-générée. Dans [TrY 80] on cherche à réduire l'initiative laissée au programmeur à l'utilisation d'une macro-définition (COBOL) : c'est la macro-définition syntaxique, où les paramètres effectifs doivent répondre à certaines contraintes d'ordre syntaxique qu'on impose à la définition.

1. Les données

2. Les traitements

2. Les traitements

On regarde ici la première fonction "intéressante" : *putphyl :

(de *putphyl (nomphyl attphyl)
   (let ((phyl (makephyl nomphyl attphyl)))
        (ins phylt phyl)
        (mapv '(lambda (oper)
                  (let ((drap (makedrap)))
                       (ins (phyloper oper) drap)
                       (ins (operphyl phyl) drap)))
              opert))
   (*putphyl-ana nomphyl attphyl))

On retrouve dans cette fonction les principales facultés d'abstraction du langage Lisp :

Les premiers points illustrent les possibilités d'abstraction de données du langage ; le dernier point concerne les traitements : c'est celui-là qu'on regarde maintenant.

2.1. dérivation de la fonction mapv

Mapv n'est pas (dans LeLisp V15.2) une fonction prédéfinie. C'est l'application de mapc (prédéfinie) sur le type liste – les listes pour lesquelles le premier élément n'est pas significatif. Ceci suggère évidemment l'emploi d'une macro-définition

(mapv fct ref1 ... refN)
; donne :
(mapc fct (cdr ref1) ... (cdr refN))

De même si mapc n'était pas prédéfinie, on introduirait la macro-définition :

(mapc fct lst1 ... lstN)
; donne :
(let ((aux1 lst1) ... (auxN lstN))
     (while (and aux1 ... auxN)
            (fct (nextl aux1) ... (nextl auxN))))

On pourrait ensuite affiner nextl, si la fonction n'était pas prédéfinie :

(nextl arg)
; donne :
(prog1
   (car arg)
   (setq arg (cdr arg)))

On affinerait ensuite prog1, etc. ,jusqu'à arriver aux symboles primitifs implantés effectivement par le langage.

On voit donc que le langage permet une « expression de haut niveau » du problème (mapc) sur les éléments primitifs « de bas niveau » (while, next, ...) par des schémas de transformation qui restent transparents à l'utilisateur – c'est l'interprète Lisp qui se charge de réécrire le programme.

Pourquoi présenter cet aspect du langage sous la rubrique « macro-génération » ? c'est que volontairement on se place dans l'optique d'une exécution efficace des programmes : dans l'absolu, parce qu'il est toujours désagréable d'attendre inutilement ; pour les domaines spécifiques où l'efficacité est un impératif crucial – le Temps Réel. Si l'on se plaçait dans une autre optique, on pourrait se limiter à toujours programmer en Lisp, dont la puissance d'expression est suffisante pour couvrir la totalité des techniques de programmation offertes dans les langages – H. Abelson et G. Sussman donnent dans [AbS 83] un panorama complet de la programmation par le biais du lanage Scheme, un dialecte de Lisp.

2.2. l'expression dans un langage de haut niveau

Un langage de « haut niveau », comme Ada, est assez rebelle à l'expression de l'affinage d'un algorithme dans les termes du langage.

Pour représenter la fonction mapv, on pourrait chercher à mettre encore en pratique la généricité d'Ada, mais ceci semble mal adapté ; il faudrait :

Plus simplement on recopie le code et de ce fait on disperse la connaissance.

Dans l'exemple, la relative simplicité de la fonction Lisp permet de facilement identifier les étapes de dérivation du programme Lisp dans le texte du programme Ada :

schéma d'identification des programmes Lisp et Ada
schéma d'identification des programmes Lisp et Ada

En inversant le rôle des partenaires – Lisp et Ada – on perd en automatisation du processus de traduction mais on gagne en faisabilité. Le programme est écrit en Ada, les occurrences d'apparition de la fonction mapv sont les occurrences d'utilisation su « texte » mapv : par affinage, via les « textes », du programme Ada, on reconstruit formellement la fonction Lisp, mais en travaillant dans le langage « exigeant » – « exigeant », si l'on admet que Lisp est plutôt un langage « accomodant ».