【问题标题】:Is this Racket macro written in an idiomatic style?这个球拍宏是用惯用的风格写的吗?
【发布时间】:2018-04-09 01:47:09
【问题描述】:

我的儿子和我正在一起学习 Racket,并且正在构建一个非常简单的基于文本的冒险,以直接从 REPL 中使用。因此,例如,玩家可以输入(go 'north)(take 'apple)

在完成了一些基本工作后,我儿子认为引用名词有点痛苦(奇怪的是,括号并没有打扰他!),所以我们用宏修改了一下,我们确实得到了一些工作,但它需要一个显式的函数和一个相应的宏,例如

    (define (do-take item) ...)
    (define-syntax (take stx)
      (define item (cadr (syntax->datum stx)))
      (datum->syntax stx `(do-take ',item)))

我认为我们可以做得比这更好,所以我阅读了更多内容并想出了这个:

    (require (for-syntax racket/syntax))
    (define-syntax (define-verb stx)
     (syntax-case stx ()
       [(_ (verb noun) body-first body-rest ...)
        (with-syntax ([verb-fun (format-id stx "do-~a" #'verb)])
          #'(begin
              (define-syntax-rule (verb noun) (verb-fun 'noun))
              (define (verb-fun noun) body-first body-rest ...)))]))

所以现在,我们可以写(define-verb (take item) ...),REPL 的玩家可以输入(take apple)

我的问题是,考虑到我们想要实现的目标,这是否是一种合理的方法,或者是否有更简单/惯用的方法来实现相同的目标?

【问题讨论】:

    标签: macros racket


    【解决方案1】:

    一般来说,我建议做的主要事情是使用syntax/parse 库。它有更多用于解析语法的工具。您甚至可以使用define-syntax-parser 之类的形式让您的宏更加简洁。使用syntax/parse 重写您的代码(删除那一行,因为它似乎没有做任何事情),您的宏将如下所示:

    #lang racket
    (require syntax/parse/define
             (for-syntax syntax/parse racket/syntax))
    (define-syntax-parser define-verb
      [(_ (verb:id noun) body ...+)
       (define/syntax-parse verb-fun (format-id stx "do-~a" #'verb))
       #'(begin
           (define-simple-macro (verb noun) (verb-fun 'noun))
           (define (verb-fun noun) body ...))])
    

    这在您给出的示例之上为您提供了一些不错的东西:

    • :id 确保verb 是文字标识符,而不是表达式。
    • ...+ 表示您只需要一个 body 模式,而不是两个。
    • 使用define/syntax-parse 意味着您的代码不会比with-syntax 缩进更多。 (尽管这是一个偏好问题。)

    【讨论】:

    • syntax-quote 需要在 begindefine-syntax-rule 之上才能使宏起作用。
    • 我很难理解你在说什么。
    • 您评论说不确定define-syntax-rule 的用途。它应该在#'(begin ...) 中。对不起,我不清楚!
    • 啊,好吧。那么在这种情况下,我会相应地更新我的答案(和问题)。谢谢。 :)
    猜你喜欢
    • 2014-01-22
    • 2012-07-04
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2012-04-09
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多