Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 使用Racket宏生成require子句_Macros_Metaprogramming_Racket_Language Extension - Fatal编程技术网

Macros 使用Racket宏生成require子句

Macros 使用Racket宏生成require子句,macros,metaprogramming,racket,language-extension,Macros,Metaprogramming,Racket,Language Extension,好吧,我一定很傻。我正在尝试创建一个宏(一个更大任务的一部分),该宏给定一个函数,将其包装在自己的子模块中,然后要求它,这样定义的函数就不会与周围的术语混淆,但它们的主模块的其余部分可以正常使用它们。也许这不是一个好主意,但请幽默我——我不明白为什么这不可能 我在两个文件中得到了下面的最小代码示例 tinylang.rkt: (provide (all-defined-out)) (define-syntax (modularise stx) (syntax-case stx () [(_

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

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

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
    ))]))
#lang racket
(require "tinylang.rkt")
(modularise (lambda () (display "this works!")))
; the following line would make everything work!
;(require (submod "." testmodule))
(working)
tinyimp.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
    ))]))
#lang racket
(require "tinylang.rkt")
(modularise (lambda () (display "this works!")))
; the following line would make everything work!
;(require (submod "." testmodule))
(working)

我对在这个网站上乱发问题感到内疚,我觉得这些问题对我来说应该是微不足道的,但我仍然不清楚在什么阶段会发生什么。如果有人知道一个好的资源(书、讲座、论文),我真的很高兴听到。我知道Racket文档的内容非常广泛,但我经常会错过其中解释中的关键细节。

是的,宏生成的requires和provides很复杂。它们的关键是require规范的词法范围(即
(submod“.testmodule)

从:

需要。。。require规范的生成器确定绑定的范围

换句话说,require规范和所需标识符的使用必须具有相同的范围

以下是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)))]))

虽然我不知道你是否会觉得它有用,但我写道。好吧,我的直觉是,语法/标识符
nm
是用词法信息创建的,这将它置于新模块
mod
之外。也许我错了。不管怎样,我都不知道如何解决这个问题。@GregHendershott,是的,我偶然发现了这一点——我会更加关注它。谢谢你的指点,也许我应该仔细研究一下。你的问题把我难住了。因为这和我在电视上看到的一个问题有关users@racket-上周,我刚刚提到了lang.org。我在你的另一篇文章中提到了这一点,但是Matthew Flatt最近的Clojure/West谈话解释了很多关于Racket宏的内容(尽管可能不是这个确切的问题):对,我确实已经通过反复试验发现,
require
的位置是至关重要的,所以我想下一个合乎逻辑的步骤就是您提出的。看到这个问题和我前面的问题的答案,我想“拼接”代码的方法确实像您所展示的那样,使用
和语法
。无论如何,再次非常感谢你!我觉得我好像还没有RTFM,所以我会更加努力地去理解写下来的内容。我认为像你这样根据需要学习是一条路,而且你似乎已经理解了大部分的基本原理。漫无目的地阅读文档而没有特定的目标通常会导致没有任何保留,至少对我来说是这样。