Macros 将语法列表用作函数的形式参数

Macros 将语法列表用作函数的形式参数,macros,racket,Macros,Racket,这是一个场景:给定一个形式为[sym…](例如[ab]和[ab cd])的模式,我希望生成(使用宏)函数来连接模式中的符号,但也将它们作为参数提供。例如,[ab]转换为某种形式 (define (ab a b) body) 在某些情况下,有人通过名为信号列表的语法类帮助我生成函数名。在下面的代码中,我可以将信号模式变量与形式为(sig…)的模式匹配,然后使用它生成所需的函数定义 (define-syntax (define-something stx) (syntax-parse s

这是一个场景:给定一个形式为
[sym…]
(例如
[ab]
[ab cd]
)的模式,我希望生成(使用宏)函数来连接模式中的符号,但也将它们作为参数提供。例如,
[ab]
转换为某种形式

(define (ab a b) 
  body)
在某些情况下,有人通过名为
信号列表
的语法类帮助我生成函数名。在下面的代码中,我可以将
信号
模式变量与形式为
(sig…
)的模式匹配,然后使用它生成所需的函数定义

(define-syntax (define-something stx)
  (syntax-parse stx
    [(_ (signals:signal-list body ...))
     (syntax-parse #'signals
       [(sig ...)
        #'(define (signals.concatenated-ids sig ...)
               body ...)])]))
与此宏匹配的示例:

(define-something
  ([a b] 'body))
扩展到
(定义(ab a b)'body)

但是如果我想生成多个函数定义,宏是如何工作的呢?例如:

(define-something
  ([a b] 'body)
  ([c d e] 'body))
=>
(begin (define (ab a b) 'body)
       (define (cde c d e) 'body))
我可以在第一次语法分析的模式中添加省略号:

((信号:信号列表体…)


但是我不能使用第二个语法解析来匹配
信号
,因为它需要省略号。有没有一种不同的方法来“解构”信号,这样我就可以使用它的内容作为函数的形式参数,这与使用省略号兼容

要直接回答您的问题,您可以将
#'(信号…
(代替现有的
#”信号
)传递到内部
语法解析
调用


作为概念证明,我编写了宏的
语法用例
版本(因为我还不知道
语法解析
)。您应该能够轻松地将相同的技术应用于
语法分析

(定义语法(定义outerstx)
(定义(使名称为paramstx)
(基准->语法outerstx
(字符串->符号
(应用字符串附加)
(地图符号->字符串(语法->基准参数‘‘‘‘‘‘‘)’)
(定义(在STX中命名)
(语法大小写innerstx()
(()
#'())
((参数…)静止…)
(使用语法((name(make name#’(param…))
((下一个…(命名)(其余…))
#"(下一个名字)("""))
(语法大小写outerstx()
((((参数…)体…)
...)
(使用语法(((名称…(生成名称)((参数…))))
#'(定义值(名称…)
(值(λ(参数…)
身体…)
...))))))

已经定义了多个函数,所以我不确定您在问什么?请注意,这个答案之所以有效,是因为它在模式和模板中使用了相同数量的省略号。确实如此,我理解它为什么这样做,但由于提供组合ID作为形式参数的额外要求,我感到相当困惑。我真的应该对语法类做更多的研究,以正确理解正在发生的事情。我相信答案是很琐碎的。宏上的Racket文档对那些早餐不咀嚼宏的人来说不是那么友好。这听起来像是在定义新的模式变量<代码>语法分析是一种(相当重要的)方法。正如Chris所建议的,
和语法是定义局部模式变量的一种更简单的方法。使用
语法解析定义局部模式变量的惯用方法是使用
:with
,例如
:with((sig…)#信号
谢谢你的回答,它引导我找到了解决方案。如果其他人无意中发现了这个问题:我没有使用内部语法解析,而是使用
和syntax
来匹配模式
((sig…)
)和
#'(信号…
语法。第一个语法分析的主体如下所示:
(带有语法([((sig…))(signals…))(signals…))(signals())
。我缺少的关键洞见是,确实完全可以通过模式匹配来“去构造”事物。这对我来说应该是显而易见的,但事实并非如此。非常感谢。删除文本列表,
syntax parse
是替换
syntax case
:)