【问题标题】:Racket macro that generates a nested module error生成嵌套模块错误的球拍宏
【发布时间】:2018-07-15 20:09:59
【问题描述】:

在尝试使用球拍的宏时,我偶然发现了一个定义,起初我并不明白为什么它被拒绝了。代码很短,否则可能没用,但如下:

#lang racket
(define-syntax (go stx)
  (syntax-case stx ()
    [(_ id)
     #'(module mod racket
         (define it id))]
    ))
(go 'dummy)

投诉是quote: unbound identifier; also, no #%app syntax transformer... 如果我手动将(define it id) 内联到(define it 'dummy),那么它可以工作。 我有预感' 即。由#lang racket 绑定的(go 'dummy) 中的quote 在子模块mod 中不被识别为相同的绑定,即使在语法上它是相同的字母序列。如果我通过如下往返来去除所有词汇上下文的虚拟内容:

(with-syntax ([ok (datum->syntax #f (syntax->datum #'id))])

下面的模式匹配 (_ id) 并将 it 的定义替换为 (define it ok) 然后一切都很好。

#lang racket
(define-syntax (go stx)
  (syntax-case stx ()
    [(_ id)
     (with-syntax ([ok (datum->syntax #f (syntax->datum #'id))])
       #'(module mod racket
           (define it ok)))]
    ))
(go 'dummy)

我认为我的困境是由卫生系统造成的。但是,是否有更直接的解决方案可以让球拍编译器相信这些标识符,即。 quote 没有这个样板真的一样吗?

【问题讨论】:

    标签: macros racket hygiene


    【解决方案1】:

    您为id 插入的表达式:

    (module mod racket
      (define it id))
    

    将在模块的上下文中进行评估。 因此,语法上下文 id id 需要与 子模块的上下文。

    您描述了一种删除现有上下文的方法。这是另一个:

    #lang racket
    (require (for-syntax racket/base))
    
    (define-syntax (go stx)
      (syntax-case stx ()
        [(_ id)
         (with-syntax ([id (syntax->datum #'id)])
           #'(module mod racket
               (provide it)
               (define it id)))]))
    
    (go 42)
    (require (submod "." mod))
    it
    

    在大多数宏中,保留上下文是一件好事,所以 不得不“样板”来删除它对我来说似乎没问题。

    当然,如果你有很多样板,那就写 为您插入样板的宏:-)

    【讨论】:

    • 感谢您的反馈。只是出于好奇,是否有另一种解决方案可以直接让球拍相信顶级#lang 球拍模块和带有球拍扩展器的嵌套模块是相同的?例如,有一个 namespace-attach-module 函数,它使 Racket 相信某些特定模块的顶级 require 和同一模块的 namespace-require 在使用 eval 时实际上是一回事。这就是您在 6 月 17 日对另一个问题的回答中所显示的内容。
    • 如果你想让你的表达式有相同的范围,那么为什么要把它们放在子模块中呢?
    • 我想这个问题确实是人为的。我认为这可能有用的唯一想法是嵌套模块仅包含顶级绑定的子集,这样您就可以轻松拒绝某些表达式。我不相信这会保证新的 API 工具。
    • 最好在syntax/strip-context 中使用strip-context,因为这样会保留源位置。
    猜你喜欢
    • 1970-01-01
    • 2019-10-27
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多