provided using mit-scheme
The only modification is from (cthen (make-syntactic-closure env '(it) (third exp))) to (cthen (third exp))
In brief, what difference does make-syntactic-closure make?
(define-syntax aif
(sc-macro-transformer
(lambda (exp env)
(let ((test (make-syntactic-closure env '(it) (second exp)))
(cthen (make-syntactic-closure env '(it) (third exp)))
(celse (if (pair? (cdddr exp))
(make-syntactic-closure env '(it) (fourth exp))
#f)))
`(let ((it ,test))
(if it ,cthen ,celse))))))
(let ((i 4))
(aif (memv i '(2 4 6 8))
(car it)))
(define-syntax aif
(sc-macro-transformer
(lambda (exp env)
(let ((test (make-syntactic-closure env '(it) (second exp)))
(cthen (third exp))
(celse (if (pair? (cdddr exp))
(make-syntactic-closure env '(it) (fourth exp))
#f)))
`(let ((it ,test))
(if it ,cthen ,celse))))))
(let ((i 4))
(aif (memv i '(2 4 6 8))
(car it)))
I tried the two version of macro, but got the same result.
A syntactic closure captures the syntactic environment and allows identifiers present in it to be used in the form as variables, instead of having a meaning provided by the environment of the macro transformer (It also lets you specify a list of free names like
itin this case that can be set or otherwise used in the macro body and have that binding used in the expanded form; basically it removes those names from the given environment)An example:
With the first version of your
aifmacro, this evaluates to'a. With the second version, it generates an errorUnbound variable: x, because in the macrocthenis a list, not a syntactic closure, andxis unbound in the macro transformer so it can't be found when the expanded body is evaluated.