在尝试使用球拍的宏时,我偶然发现了一个定义,该定义最初对我来说并不明显,为什么它被拒绝了。代码简短,否则可能没用,但是如下:
#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)
,则可以正常工作。
我有个'
的预感,即。 quote
的{{1}}中受(go 'dummy)
绑定的#lang racket
在子模块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
真的没有这个样板吗?
答案 0 :(得分:0)
在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
在大多数宏中,保留上下文是一件好事,因此 对我来说,必须“锅炉板”将其卸下似乎可以。
当然,如果您遇到很多样板,那就写 一个为您插入样板的宏:-)