scheme
Regeling macro's
Zoeken…
Hygiënische en referentieel transparante macro's met syntax-regels
Het grootste voordeel van LISP en Scheme ten opzichte van andere reguliere programmeertaal is hun macrosysteem. In tegenstelling tot de C-preprocessor en andere macrotalen, nemen schemamacro's ontlede code als invoer en retourneren uitgebreide code als uitvoer. Dit is een van de toepassingen van Scheme's "code is data" -zin en het is wat de taal zo krachtig maakt.
Macro's in Schema worden gemaakt met define-syntax , waarmee een macro op een aantal manieren kan worden gedefinieerd. De eenvoudigste methode is om syntax-rules , die patroonafstemming gebruiken om de invoercode om te zetten in de uitvoercode.
Dit voorbeeld maakt een eenvoudig for item in list en for list as item itemsyntaxis voor het herhalen van elementen in een lijst:
(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 ...))))
Deze twee macro's kunnen vervolgens als volgt worden gebruikt en bieden een meer dwingende stijl:
(let ((names '(Alice Bob Eve)))
(for name in names
(display "Hello ")
(display name)
(newline))
(for names as name
(display "name: ")
(display name)
(newline)))
Het uitvoeren van de code levert de verwachte uitvoer:
Hello Alice
Hello Bob
Hello Eve
name: Alice
name: Bob
name: Eve
De meest voorkomende fout om op te letten, is niet de juiste waarden doorgeven aan een macro, wat vaak resulteert in een nutteloze foutmelding die van toepassing is op de uitgebreide vorm in plaats van de macro-aanroep.
De for syntaxisdefinities hierboven niet controleren of ze worden doorgegeven een identificatie en een lijst, dus langs een ander type zal resulteren in een fout wijst naar het for-each oproep in plaats van de for oproep. Foutopsporing verslaat het doel van de macro, dus het is aan de gebruiker om de controles in te voeren en gebruiksfouten te melden, die vervolgens tijdens het compileren kunnen worden gevangen.