Macros 如何绑定";“休息”;方案中宏中值列表的变量

Macros 如何绑定";“休息”;方案中宏中值列表的变量,macros,scheme,racket,Macros,Scheme,Racket,我想制作一个用于编写匹配扩展的帮助宏。我有这样的想法: (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 v

我想制作一个用于编写匹配扩展的帮助宏。我有这样的想法:

(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))))
(define-syntax-rule (define-my-expander (id vars ...) body)
  (define-match-expander id
    (λ (stx)
      (syntax-case stx ()
        [(_ vars ...)
         body]))))
所以我想要一个宏来完成这个让绑定。我从以下内容开始:

(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))))
(define-syntax-rule (define-my-expander (id vars ...) body)
  (define-match-expander id
    (λ (stx)
      (syntax-case stx ()
        [(_ vars ...)
         body]))))
但是
match let
在转换时间中没有定义

第一个问题是,有没有其他方法可以做到这一点(我的意思是制造扩展器)?也许在plt方案中已经有一些类似的东西我不知道,或者我在某种程度上做错了

不管第一个问题的答案是什么,如果我想将变量列表绑定到宏中的值列表,我应该怎么做

编辑:与Eli的answer宏结合使用,现在看起来如下所示:

(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))))
(define-syntax-rule (define-my-expander (id vars ...) body)
  (define-match-expander id
    (λ (stx)
      (syntax-case stx ()
        [(_ vars ...)
         body]))))

我不知道你想要实现什么,但我猜这是正确的方向:

(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)
稍有不同。因此,一般来说,使用
语法case
进行模式匹配要容易得多。除了更简单之外,当出现错误时,它还会给出一些合理的错误消息,而不是您的代码所得到的信息。

我不知道您试图实现的是什么,但我猜这是朝着正确的方向发展的:

(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)
稍有不同。因此,一般来说,使用
语法case
进行模式匹配要容易得多。除了更简单之外,当出现错误时,它还会给出一些合理的错误消息,而不是您从代码中得到的信息。

谢谢,这很有帮助,帮助我解决了问题。为了完整性起见,如果我不是在做扩展器,而是说,宏,它扩展成具有lambda的东西,它接受一个列表,并且我想将列表元素绑定到宏参数?大多数情况下,当您使用模式匹配编写宏时,它是有效的。但是每隔一段时间(当您编写更高级的宏时,可能会更频繁地出现错误消息等问题),您需要将它们转换为一个列表。为此,您可以使用类似于
(syntax->list#'(stuff…)
——它接受括号中的syntax对象,并将其转换为syntax对象列表。谢谢,这很有帮助,帮助我解决了问题。为了完整性起见,如果我不是在做扩展器,而是说,宏,它扩展成具有lambda的东西,它接受一个列表,并且我想将列表元素绑定到宏参数?大多数情况下,当您使用模式匹配编写宏时,它是有效的。但是每隔一段时间(当您编写更高级的宏时,可能会更频繁地出现错误消息等问题),您需要将它们转换为一个列表。为此,您可以使用类似于
(syntax->list#'(stuff…)
——它接受带括号的syntax对象,并将其转换为syntax对象列表。