【问题标题】:Racket macros - making pairs球拍宏 - 配对
【发布时间】:2012-04-09 06:40:41
【问题描述】:

我刚刚开始深入研究 Racket 宏,并且正在尝试制作一个简洁的简单宏定义宏。我想扩展一个这样的表达式:

(macro id
    (param) replacement1
    (params ...) replacement2)

变成这样:

(define-syntax id
    (syntax-rules ()
        ((id param) replacement1)
        ((id params ...) replacement2)))

所以原始表达式的cddr变成了表达式对(用于syntax-rules body),id被插入到每一对的car中。

仅使用语法规则提供的模式匹配时,我在递归思考时遇到了麻烦(我一直想像处理普通列表一样操作表达式)。我应该使用什么样的模式?或者,我可以以某种方式将其作为普通列表进行操作,然后取消引用结果以用于扩展吗?

非常感谢

编辑 - 暂定解决方案,由 Taymon 的回答提供信息

我在这里的部分好奇心是关于摆脱那些配对括号。我研究了语法案例,但有点困惑,所以尝试纯粹使用模式匹配子语言来做。我最终使用 Taymon 的宏和另一个宏来“配对”给定的模板(它有点像累加器函数):

(define-syntax-rule (macro-aux id ((param ...) expr) ...)
  (define-syntax id
    (syntax-rules ()
      ((id param ...) expr)
      ...)))

(define-syntax pairize
  (syntax-rules ()
   ((pairize id (pairs ...) p b) (macro-aux id pairs ... (p b)))
   ((pairize id (pairs ...) p b rest ...) (pairize id (pairs ... (p b)) rest ...))))

(define-syntax macro
  (syntax-rules ()
    ((macro id tpl-expr ...) (pairize id () tpl-expr ...))))

【问题讨论】:

    标签: macros scheme racket define-syntax


    【解决方案1】:

    可以构建一个宏扩展器,将语法表达式作为常规 Racket 数据进行操作。但是,在这种情况下,这并不是真正必要的。

    我推荐的一件事是稍微改变你的语法,这样每个模式替换对都被括在括号中。像这样:

    (macro id
      [(param) replacement1]
      [(params ...) replacement2])
    

    完成后,您可以使用常规模式匹配宏。这是我的看法:

    (define-syntax-rule (macro id [(param ...) replacement] ...)
      (define-syntax id
        (syntax-rules ()
          [(id param ...) replacement] ...)))
    

    【讨论】:

    • 谢谢!在看到您的示例之前,我并不完全了解省略号在模式中的工作原理,并且在暂定解决方案中使用了您的规则。
    【解决方案2】:

    Taymon 是对的,但也可以使用省略号 将模式替换对括在括号中,使用来自syntax/parse~seq

    (require syntax/parse/define)
    (define-simple-macro (macro id (~seq (param ...) replacement) ...)
      (define-syntax id
        (syntax-rules ()
          [(id param ...) replacement] ...)))
    

    哪个可以像你最初想要的那样使用:

    (macro id
      (param) replacement1
      (params ...) replacement2)
    

    【讨论】:

      猜你喜欢
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 2013-04-10
      • 2012-02-27
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多