定义接受可变数量参数的宏生成的宏

2024-02-11

我正在尝试编写一个宏生成宏,其中它生成的宏采用可变数量的参数。

我想知道是否有办法使以下代码工作:

(define-syntax-rule (greet name)
  (define-syntax-rule (name args ...)
    (printf "hello ~a~n" (list args ...))))

现在它说“不pattern variables before ellipsis in template in: ..."

如果我把内心define-syntax-rule它本身工作得很好,那么为什么当它由另一个宏生成时它就不起作用呢?


至少有 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-定义,每个元级别都有一个定义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

定义接受可变数量参数的宏生成的宏 的相关文章

  • 如果多个字符在方案中彼此相邻,则从列表中删除它们

    我必须制作一个 Dr Racket 程序 如果列表中的字母与其本身相同 则将其从列表中删除 例如 z z f a b b d d 将变为 z f a b d 我已经为此编写了代码 但它所做的只是从列表中删除第一个字母 有人可以帮忙吗 lan
  • 如何从 2 个列表创建关联列表?

    在 DrScheme 中 如何从 2 个列表创建关联列表 例如 我有 y 1 2 3 x a b c 而且我要 z a 1 b 2 c 3 假设方案 因为你的最后两个问题是关于方案 define x 1 2 3 define y 4 5 6
  • BSL(如何设计程序):如何将代码从单独的文件导入到定义区域?

    我对 BSL 有疑问 我想将我的代码分成单独的辅助文件并使用 require auxiliary function rkt 首先将分离的代码导入到定义区域 然而它并没有像想象的那样工作 虽然没有给出明确的错误 但似乎 DrRacket 根本
  • 从 procedure 形式转换为 let 形式

    我在scheme中编写了这个程序形式的代码 我需要将其更改为let形式 这是程序表单代码 define PI 3 14159265 define areac lambda d PI d 2 d 2 define volumec lambda
  • 方案中的埃拉托色尼筛选在其过滤过程中使用局部状态的突变

    While 回答最近question我想出了以下代码 实现了埃拉托斯特尼筛的变体 反复剔除初始的2 n顺序 尽早停止 define sieve2 n let ls makelist n let loop ls ls next sievehe
  • 调用宏中的其他函数

    如何在宏中调用其他函数 宏 以下似乎不起作用 即使我定义bar with define syntax define bar hello define syntax foo stx syntax case stx a b bar Racket
  • 如何在Scheme中列出评估的所有中间步骤

    例如 如果有表达式 map lambda x add1 x 1 2 3 其评估结果为 2 3 4 如何显示所有中间步骤 在本例中为 map lambda x add1 x 2 2 3 map lambda x add1 x 2 3 3 我认
  • DrRacket、R5RS和错误程序

    我喜欢 DrRacket IDE 但目前我正在构建一个我希望独立于它的宠物项目 这意味着我致力于仅使用 R5RS 标准程序 问题是 在 DrRacket 中有一个名为 错误 的过程 我想继续使用它 但我在标准中找不到它 我想知道是否有一种方
  • 使用trace显示racket中的程序

    我一直在完成 SICP 的最后几个练习第 1 章 其中几个练习使用高阶函数 目前 我正在尝试调试 1 45 解决方案中的一个问题 该问题引发了元数不匹配 产生误差的函数是对定点函数求解器两次应用平均运算的结果 这将使我的调试工作更加努力a
  • make 函数从何而来?

    这段代码的工作原理 define list of events for list date code in query odc select date code from attendance where student id and te
  • 在一个函数中生成幂集,没有显式递归,并且在 Racket 中仅使用最简单的原语

    Note 这是对家庭作业的奖励 但我花了太长时间尝试却毫无结果 非常感谢帮助 但我认为没有必要 Premise 为数字列表生成幂集 但不使用任何辅助函数 显式递归 循环或除cons first rest empty empty else l
  • 编码霍夫曼树方案[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在尝试编写一个函数 codeWords t 它遍历霍夫曼树 添加 0当它向左移动时 添加 1当它向右时 并以叶子上的
  • 如何避免 Racket 中的加载循环?

    我有一套非常简单的 rkt来源 例如其中的 a rkt 和 b rkt 我希望能够写 require a rkt 在 b rkt 中 反之亦然 现在我面临有关 加载周期 的错误 我可以在不添加单元的情况下使用裸模块解决这个问题吗 Racke
  • 方案相当于元组拆包是什么?

    在Python中 我可以做这样的事情 t 1 2 a b t a 将是 1 b 将是 2 假设我有一个列表 1 2 在方案中 有什么办法可以做类似的事情let 如果有什么区别的话 我会使用 Racket 在球拍中你可以使用match htt
  • 在Scheme 中是否有相当于Lisp 的“运行时”原语?

    根据SICP 第 1 2 6 节 http mitpress mit edu sicp full text book book Z H 11 html sec 1 2 6 练习 1 22 大多数 Lisp 实现都包含一个称为运行时的原语 它
  • schema 中的方法和属性:Scheme 中是否可以实现 OOP?

    我将用一个简单的例子来说明我的问题 在 Java C 或任何其他 OOP 语言中 我可以创建一个pie类的方式类似于 class Apple public String flavor public int pieces private in
  • 有没有办法检查一个列表的所有元素是否都包含在球拍的另一个列表中?

    我想要一个执行类似操作的函数 gt function 1 2 3 4 1 2 3 4 5 t 在这种情况下返回 t 因为第一个列表的所有元素都包含在第二个列表中 有没有一个函数可以做到这一点而不必担心顺序 在这种情况下 您不会将列表进行比较
  • 方案:为什么内部定义比外部定义快?

    我尝试运行下面的程序 define odd internal x define even x if zero x t odd internal sub1 x if zero x f even sub1 x define odd extern
  • 方案中的多维向量?

    我之前问过一个关于方案中数组的问题 结果它们被称为向量 但在其他方面基本上与您期望的相同 有没有一种简单的方法可以在 PLT 方案中处理多维 arrays 向量 出于我的目的 我想要一个名为make multid vector或者其他的东西
  • 如何在球拍中查看扩展宏?

    我得到了这个答案https stackoverflow com a 70318991 https stackoverflow com a 70318991关于编写一个简单的宏来记录宏扩展时的时间 然后始终返回该时间 lang racket

随机推荐