如果我有一个文件test.scm:
(define foo 5)
然后使用REPL:
(define foo 2)
foo
==> 2
(define bar
(lambda ()
(load "test.scm")
foo))
foo
==> 2
(bar)
==> 5
foo
==> 5
换句话说,在一个词汇上下文中加载文件允许绑定转义到顶层。为什么会这样,有没有办法按照C #include
包含另一个文件,即执行命令就好像它们在那时被拼接到代码中一样?
答案 0 :(得分:2)
如果load
执行的代码能够访问load
表单的词汇上下文,则它不会是词汇上下文。
如果load
是一个宏而不是一个函数,情况会有所不同 - 但即使这样,标准的R5RS宏也是卫生的,并且不容易弄乱词汇背景。
但是,您可以编写一个defmacro
样式的宏,通过读取文件并返回包含从文件中读取的所有内容的begin
表单来执行您所要求的内容。
(define-macro (include file)
(let ((read-forms
(lambda ()
(let loop ((forms '()))
(let ((form (read)))
(if (eof-object? form)
(reverse forms)
(loop (cons form forms))))))))
(with-input-from-file file
(lambda ()
(cons 'begin (read-forms))))))
请注意define-macro
是非标准的。您必须确定是否以及如何使其工作,具体取决于您的Scheme实现。
答案 1 :(得分:1)
见 http://web.mit.edu/scheme_v9.0.1/doc/mit-scheme-user/Loading-Files.html
procedure: load filename [environment [syntax-table [purify?]]]
“环境,如果给出,则是评估文件的环境;如果没有,则使用当前的REPL环境。”
这意味着文件直接计算到repl而不是lambda闭包中。
修改强> 在SO (load "file.scm") in a New Environment in Scheme上看到这个问题如何建立新的环境。