Loading a file that defines values overwrites top-level bindings
If I have a file test.scm:
(define开发者_C百科 foo 5)
and then using the REPL:
(define foo 2)
foo
==> 2
(define bar
(lambda ()
(load "test.scm")
foo))
foo
==> 2
(bar)
==> 5
foo
==> 5
In other words, loading a file in one lexical context allows the bindings to escape to the top level. Why is this so, and is there a way to include another file as per C #include
, i.e. execute the commands as if they were spliced into the code at that point?
If the code executed by load
were able to access the lexical context of the load
form, it wouldn't be a lexical context.
The situation would be somewhat different if load
were a macro rather than a function—but even then, standard R5RS macros are hygienic and cannot easily mess with the lexical context.
However, you could write a defmacro
-style macro that does what you ask for by reading a file and returning a begin
form containing everything read from the file.
Example code:
(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))))))
Note that define-macro
is non-standard. You will have to figure out whether and how it can be made to work depending on your Scheme implementation.
see http://web.mit.edu/scheme_v9.0.1/doc/mit-scheme-user/Loading-Files.html
procedure: load filename [environment [syntax-table [purify?]]]
"Environment, if given, is the environment to evaluate the file in; if not given the current REPL environment is used."
that means that the file is evaluated directly into the repl and not in the lambda closure.
EDIT see this question on SO (load "file.scm") in a New Environment in Scheme how a new environment can be made.
精彩评论