我想创建一个帮助宏来编写匹配扩展。我有这样的事情:
(define-match-expander my-expander
(λ (stx)
(let* ([dat (cdr (syntax-e stx))]
[var1 (car dat))]
[var2 (cadr dat)])
;transformer goes here )))
所以我想要一个允许绑定的宏。我从这样的事情开始:
(define-syntax-rule (define-my-expander (id vars ...) body)
(define-match-expander id
(λ (stx)
(match-let ([(vars ...) (cdr (syntax-e stx))])
body))))
但match-let
未在转换时定义。
第一个问题是有没有其他方法这样做(制作这个扩展器,我的意思)?也许在plt-scheme中已经有类似的东西,我不知道,或者我在某种程度上做错了。
无论第一个问题的答案如何,如果我想将变量列表绑定到宏内的值列表,我应该怎么做?
编辑:结合Eli的答案宏,现在看起来像这样:
(define-syntax-rule (define-my-expander (id vars ...) body)
(define-match-expander id
(λ (stx)
(syntax-case stx ()
[(_ vars ...)
body]))))
答案 0 :(得分:4)
我不知道你想要达到的是什么,但我的猜测是朝着正确的方向前进:
(define-match-expander my-expander
(lambda (stx)
(syntax-case stx ()
[(_ (var1 var2) stuff ...)
;; use #'var1 #'var2 and #'(stuff ...) here
])))
问题在于,syntax-e
用于“解包”一个语法对象,并为您提供它所拥有的内容 - 但实际内容可能会让您感到惊讶。例如,(foo . (bar))
的内容与(foo bar)
的内容略有不同。所以一般来说,使用syntax-case
为您进行模式匹配更容易 。除了更容易之外,它还会在出现错误时提供一些明智的错误消息,而不是您的代码所带来的错误消息。