至少有 3 种“风格”可以做到这一点。
1:省略号——分别引用每个省略号
苏加德已经回答了 https://stackoverflow.com/questions/53863620/defining-macro-generated-macros-that-take-in-variable-number-of-arguments/53866670#53866670你可以替换每一个...
在体内与(... ...)
,这样它就会被解释为属于内部宏的文字省略号,而不是属于外部宏的“元”省略号:
(define-syntax-rule (greet name)
(define-syntax-rule (name args (... ...))
(printf "hello ~a~n" (list args (... ...)))))
优点:灵活,可以混合文字(... ...)
和元...
在体内自由地形成椭圆
缺点:如果你没看过的话,看起来会很混乱(... ...)
before
2:省略号-引用整个内部宏定义
然而,把(... <something>)
围绕某事不仅限于...
。如果你把整个模板放在那里,任何...
该模板中的 s 也将被“引用”,被视为文字而不是元,以相同的方式:
(define-syntax-rule (greet name)
(...
(define-syntax-rule (name args ...)
(printf "hello ~a~n" (list args ...)))))
优点:如果您有更大的嵌套深度,则不需要((... ...) (... ...))
与选项 1 一样,您只需要(... <something-containing (... <something>)>)
缺点:刚性,如果你放(... <something>)
围绕某事物,您永远不能在该事物内部使用元省略号。您无法像使用样式 1 或 3 那样自由地混合文字省略号和元省略号。
3:创建一个模式变量来表示文字省略号
这是另一种方法,我发现它不那么令人困惑,但它需要使用define-simple-macro
代替define-syntax-rule
,这样您就可以使用绑定新的模式变量#:with
.
(require syntax/parse/define)
(define-simple-macro (<name> <arguments>)
#:with <pattern-variable> <expression>
<body-expression>)
您可以使用#:with
绑定一个ooo
模式变量为文字省略号:#:with ooo (quote-syntax ...)
(require syntax/parse/define)
(define-simple-macro (greet name)
#:with ooo (quote-syntax ...)
(define-syntax-rule (name args ooo)
(printf "hello ~a~n" (list args ooo))))
优点:灵活,可以混合文字ooo
和元...
在体内自由地形成椭圆。对我来说,它看起来不像(... ...)
or ((... ...) (... ...))
.
缺点:对于更深的嵌套,您可能需要多个#:with
-定义,每个元级别都有一个定义。