Les macro-expansions
Rappels sur l'évaluation et l'application
Évaluation applicative : (eval o env)
Cette forme d'évaluation est utilisée pour toutes les fonctions construites avec
lambda, define, let et letrec. C'est celle qui est mise en
œuvre dans la plupart des langages de programmation, en particulier impératifs
(C, Java). Soit env l'environnement courant :
- si l'objet
oest autoévaluant, renvoyero; - si
oest un symbole, rechercher une liaison définissantodansenvet renvoyer la référence associée ; - si
oest une liste :- calculer
(eval (car o) env), soitfla fermeture résultat ; - calculer
(eval a env)pour tout élémentade(cdr o), soitvla liste des résultats ; - calculer
(apply f v).
- calculer
Application : (apply f v)
Avec :
f: fermeture de la fonction à appliquer ;v: liste des valeurs des arguments.
- Soient
el'environnement lexical def,lfla liste des paramètres formels etcle corps de la fermeture. - Construire l'environnement local
e-localconstitué des liaisons entre les paramètres formels delfet les références des valeurs correspondantes dansv. - Pour chaque expression
exprdu corpscdef, évaluer(eval expr (cons e-local e)). - Renvoyer le résultat de l'évaluation de la dernière expression de
c.
Évaluation paresseuse
L'évaluation paresseuse, ou par nécessité, consiste à retarder l'évaluation des paramètres jusqu'au moment de leur utilisation. Certains paramètres peuvent ainsi ne jamais être évalués. Ce mécanisme est nécessaire pour implémenter les conditionnelles et les boucles.
Remplacement textuel
Il y a deux niveaux de substitution : l'appel d'une macro est substitué par la définition de la macro, dans laquelle les paramètres formels ont été substitués par les arguments donnés lors de l'appel. Toutes ces substitutions sont textuelles : la structure syntaxique n'est pas prise en compte. En C, les macros avec paramètres fonctionnent de cette façon. Pour éviter certains pièges syntaxiques, il faut respecter des règles d'écriture des macros (paramètres entre parenthèses, corps entre parenthèses).
Macro-expansions par transformation de source
En Lisp et en Scheme, les macro-expansions fonctionnent par transformation de source, en tenant compte de la syntaxe. Elles permettent d'écrire des formes dites spéciales, dont l'évaluation n'est pas applicative. Les arguments sont évalués sur demande (en Lisp) ou par nécessité (en Scheme).
(define-syntax-rule <pattern> <template>)
<pattern>:(<nom-de-la-macro> <p1> ...)<p1>, ... : variables de la macro<template>: expression- Remplacement des variables dans le template
- Le résultat est une forme
- Évaluation de la forme dans l'environnement d'appel (les macros Scheme sont hygiéniques : les identificateurs introduits par le template ne capturent pas ceux du code appelant)