gpt4 book ai didi

macros - 使用 Racket 宏生成 require-clauses

转载 作者:行者123 更新时间:2023-12-02 00:05:10 25 4
gpt4 key购买 nike

好吧,我一定很蠢。我正在尝试创建一个给定函数的宏(更大项目的一部分),将其包装在自己的子模块中,然后 require s它,这样定义的函数就不会混淆周围的术语,但他们的主机模块的其余部分可以正常使用它们。也许这不是一个好主意,但请原谅我——我不明白为什么这是不可能的。

我在两个文件中得到了以下最小代码示例。

tinylang.rkt:

(provide (all-defined-out))

(define-syntax (modularise stx)
(syntax-case stx ()
[(_ func)
(with-syntax ([mod (datum->syntax stx 'testmodule)]
[nm (datum->syntax stx 'working)]
)
#`(begin

(print (list "Defining module " 'mod))(newline)

(module mod racket
(provide nm)
(define nm func)
)

(require (for-syntax (submod "." mod))) ;; at least kills a syntax error
(require (for-template (submod "." mod))) ;; doesn't help
))]))

tinyimp.rkt:

#lang racket
(require "tinylang.rkt")
(modularise (lambda () (display "this works!")))
; the following line would make everything work!
;(require (submod "." testmodule))
(working)

我对向这个网站发送垃圾邮件感到内疚,我觉得这些问题对我来说应该是微不足道的,可以用文档来解决,但我仍然不清楚在什么阶段发生了什么。如果有人知道好的资源(书籍、讲座、论文),我会很高兴听到。我知道 Racket 文档,它非常广泛,但我经常错过那里解释中的关键细节。

最佳答案

是的,宏生成的要求和提供是棘手的。它们的关键是 require-spec 的词法范围(即 (submod "."testmodule))。

来自docs :

In require ... the generator of the require-spec determines the scope of the bindings.

换句话说,require-spec 和 uses of required identifiers 必须具有相同的范围。

这是一个可用的 tinylang.rkt 版本:

#lang racket

(provide (all-defined-out))

(define-syntax (modularise stx)
(syntax-case stx ()
[(_ func)
(with-syntax ([require-spec (datum->syntax stx '(submod "." testmodule))])
#`(begin
(module testmodule racket
(provide working)
(define working func))
(require require-spec)))]))

关于macros - 使用 Racket 宏生成 require-clauses,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18852921/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com