Sök…


Hygieniska och referensgenomskinliga makron med syntaxregler

LISP och Schems största fördel jämfört med andra vanliga programmeringsspråk är deras makrosystem. Till skillnad från C-förbehandlaren och andra makrospråk tar schemamakroner en parsad kod som inmatning och returnerar utökad kod som utgång. Detta är en av tillämpningarna i Schemas fras "kod är data" och det är det som gör språket så kraftfullt.

Makron i schema skapas med define-syntax , som kan definiera ett makro på ett antal sätt. Den enklaste metoden är att använda syntax-rules , som använder mönster-matchning för att omvandla ingångskoden till utgångskoden.

I det här exemplet skapas en enkel for item in list och for list as item objektsyntax för looping över element i en lista:

(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 ...))))

Dessa två makron kan sedan användas på följande sätt, vilket ger en mer nödvändig stil:

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

Att köra koden ger den förväntade utgången:

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

Det vanligaste misstaget att leta efter är att inte överföra de rätta värdena till ett makro, vilket ofta kommer att leda till ett olämpligt felmeddelande som gäller den utvidgade formen istället för makroanropet.

Definitionerna for syntax ovan kontrollerar inte om de har skickats en identifierare och en lista, så att vidarebefordring av någon annan typ kommer att leda till ett fel som pekar på for-each samtal istället för for samtal. Felsökning av detta besegrar makrotens syfte, så det är upp till användaren att lägga in kontrollerna där och rapportera användningsfel, som sedan kan fångas vid sammanställningstiden.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow