Recherche…


Macros hygiéniques et référentiellement transparentes avec règles de syntaxe

Le plus grand avantage de LISP et de Scheme par rapport aux autres langages de programmation classiques est leur macro-système. Contrairement au préprocesseur C et aux autres langages macro, les macros Scheme prennent le code analysé en entrée et renvoient le code développé en sortie. C'est l'une des applications de l'expression «code is data» de Scheme et c'est ce qui rend le langage si puissant.

Les macros dans Scheme sont créées avec define-syntax , qui peut définir une macro de différentes manières. La méthode la plus simple consiste à utiliser syntax-rules , qui utilisent la correspondance de modèle pour transformer le code d'entrée en code de sortie.

Cet exemple crée un for item in list simple for item in list et for list as item syntaxe d' for list as item permettant de survoler les éléments d'une liste:

(define-syntax for
  (syntax-rules (in as) ; 'in' and 'as' keywords must match in the pattern
    ; When the 'for' macro is called, try matching this pattern
    ((for element in list
          body ...) ; Match one or more body expressions
     ; Transform the input code
     (for-each (lambda (element)
                 body ...)
               list))
    ; Try matching another pattern if the first fails
    ((for list as element
          body ...)
     ; Use the existing macro for the transform
     (for element in list
          body ...))))

Ces deux macros peuvent alors être utilisées comme suit, offrant un style plus impératif:

(let ((names '(Alice Bob Eve)))
  (for name in names
    (display "Hello ")
    (display name)
    (newline))
  (for names as name
    (display "name: ")
    (display name)
    (newline)))

L'exécution du code fournira le résultat attendu:

Hello Alice
Hello Bob
Hello Eve
name: Alice
name: Bob
name: Eve

L'erreur la plus courante à rechercher est de ne pas transmettre les valeurs correctes à une macro, ce qui entraîne souvent un message d'erreur inutile qui s'applique au formulaire développé au lieu de l'appel de macro.

Les for les définitions de syntaxe ci - dessus ne vérifient pas s'ils sont passés d' un identifiant et une liste, donc passer tout autre type se traduira par une erreur de pointage à la for-each appel au lieu du for appel. Déboguer cela défait le but de la macro, il est donc à l'utilisateur de mettre les contrôles et de signaler les erreurs d'utilisation, qui peuvent ensuite être interceptées au moment de la compilation.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow