生成嵌套模块错误的 Racket 宏
Racket macro that generates a nested module error
在试验 racket 的宏时,我偶然发现了一个定义,起初我并不清楚它被拒绝的原因。代码很短,否则可能没用,但如下:
#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 规则 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
没有这个样板真的一样吗?
您为 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
在大多数宏中,保留上下文是一件好事,所以
不得不 "boiler plate" 删除它对我来说似乎没问题。
当然,如果你经验丰富,那就写吧
为您插入样板的宏 :-)
在试验 racket 的宏时,我偶然发现了一个定义,起初我并不清楚它被拒绝的原因。代码很短,否则可能没用,但如下:
#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 规则 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
没有这个样板真的一样吗?
您为 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
在大多数宏中,保留上下文是一件好事,所以 不得不 "boiler plate" 删除它对我来说似乎没问题。
当然,如果你经验丰富,那就写吧 为您插入样板的宏 :-)