In this post; Ryan explains why unhygienic macros inside of unhygienic macros are often difficult.
;; the working if-it & when-it (define-syntax (if-it stx) (syntax-case stx () ((if-it test? then else) (with-syntax ((it (datum->syntax #'if-it 'it))) #'(let ((it test?)) (if it then else)))))) (define-syntax (when-it stx) (syntax-case stx () ((~ test? exp exp2 ...) (with-syntax ((it (datum->syntax #'~ 'it))) #'(let ((it test?)) (when it exp exp2 ...)))))) ;; the non-working cond-it (define-syntax (cond-it stx) (syntax-case stx (else) ((cond-it (else exp exp2 ...)) #'(begin exp exp2 ...)) ((cond-it (test? exp exp2 ...)) #'(when-it test? exp exp2 ...)) ((cond-it (test? exp exp2 ...) cond1 cond2 ...) #'(if-it test? (begin exp exp2 ...) (cond-it cond1 cond2 ...)))))
When ‘cond-it’ expands and produces an ‘if-it’ expression, the ‘if-it’ is marked by the macro expander as coming from a macro. That means its lexical context is different from the ‘it’ variables in the branches. That means that the ‘it’ variable binding produced by ‘if-it’ does not capture the ‘it’ references in the branches.
— Ryan
Post a Comment