scheme/load in guide
svn: r12466
This commit is contained in:
parent
dfd62c1e92
commit
b07b874e2e
|
@ -92,6 +92,12 @@ downloadable packages contributed by PLT Scheme users.
|
||||||
#:date "2004"
|
#:date "2004"
|
||||||
#:url "http://www.cs.utah.edu/plt/publications/oopsla04-gff.pdf")
|
#:url "http://www.cs.utah.edu/plt/publications/oopsla04-gff.pdf")
|
||||||
|
|
||||||
|
(bib-entry #:key "Flatt02"
|
||||||
|
#:author "Matthew Flatt"
|
||||||
|
#:title "Composable and Compilable Macros: You Want it When?"
|
||||||
|
#:location "International Conference on Functional Programming"
|
||||||
|
#:date "2002")
|
||||||
|
|
||||||
(bib-entry #:key "Flatt06"
|
(bib-entry #:key "Flatt06"
|
||||||
#:author "Matthew Flatt, Robert Bruce Findler, and Matthias Felleisen"
|
#:author "Matthew Flatt, Robert Bruce Findler, and Matthias Felleisen"
|
||||||
#:title "Scheme with Classes, Mixins, and Traits (invited tutorial)"
|
#:title "Scheme with Classes, Mixins, and Traits (invited tutorial)"
|
||||||
|
|
|
@ -5,12 +5,9 @@
|
||||||
|
|
||||||
@title[#:tag "modules" #:style 'toc]{Modules}
|
@title[#:tag "modules" #:style 'toc]{Modules}
|
||||||
|
|
||||||
Scheme definitions and expressions are normally written inside of a
|
|
||||||
module. Although a @tech{REPL} evaluates definitions and expressions outside
|
Modules let you organize Scheme code into multiple files and reusable
|
||||||
of a module for exploration and debugging purposes, and although
|
libraries.
|
||||||
@scheme[load] can evaluate definitions and expressions from a file as
|
|
||||||
if they appeared in a @tech{REPL} interaction, code that is meant to last for
|
|
||||||
more than a few seconds belongs in a module.
|
|
||||||
|
|
||||||
@local-table-of-contents[]
|
@local-table-of-contents[]
|
||||||
|
|
||||||
|
|
|
@ -385,3 +385,135 @@ example, since the enclosing module requires
|
||||||
instance of @schememodname[scheme/class]. Moreover, that instance is
|
instance of @schememodname[scheme/class]. Moreover, that instance is
|
||||||
the same as the one imported into the module, so the class datatype is
|
the same as the one imported into the module, so the class datatype is
|
||||||
shared.
|
shared.
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@section[#:tag "load"]{Scripting Evaluation and Using @scheme[load]}
|
||||||
|
|
||||||
|
Historically, Scheme and Lisp systems did not offer module
|
||||||
|
systems. Instead, large programs were built by essentially scripting
|
||||||
|
the @tech{REPL} to evaluate program fragments in a particular order.
|
||||||
|
While @tech{REPL} scripting turns out to be a bad way to structure
|
||||||
|
programs and libraries, it is still sometimes a useful capability.
|
||||||
|
|
||||||
|
@margin-note{Describing a program via @scheme[load] interacts
|
||||||
|
especially badly with macro-defined language extensions
|
||||||
|
@cite["Flatt02"].}
|
||||||
|
|
||||||
|
The @scheme[load] function runs a @tech{REPL} script by
|
||||||
|
@scheme[read]ing S-expressions from a file, one by one, and passing
|
||||||
|
them to @scheme[eval]. If a file @filepath{place.scm} contains
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(define city "Salt Lake City")
|
||||||
|
(define state "Utah")
|
||||||
|
(printf "~a, ~a\n" city state)
|
||||||
|
]
|
||||||
|
|
||||||
|
then it can be loaded in a @tech{REPL}:
|
||||||
|
|
||||||
|
@interaction[
|
||||||
|
(eval:alts (load "place.scm") (begin (define city "Salt Lake City")
|
||||||
|
(printf "~a, Utah\n" city)))
|
||||||
|
city
|
||||||
|
]
|
||||||
|
|
||||||
|
Since @scheme[load] uses @scheme[eval], however, a module like the
|
||||||
|
following generally will not work---for the same reasons described in
|
||||||
|
@secref["namespaces"]:
|
||||||
|
|
||||||
|
@schememod[
|
||||||
|
scheme
|
||||||
|
|
||||||
|
(define there "Utopia")
|
||||||
|
|
||||||
|
(load "here.scm")
|
||||||
|
]
|
||||||
|
|
||||||
|
The current namespace for evaluating the content of
|
||||||
|
@filepath{here.scm} is likely to be empty; in any case, you cannot get
|
||||||
|
@scheme[there] from @filepath{here.scm}. Also, any definitions in
|
||||||
|
@filepath{here.scm} will not become visible for use within the module;
|
||||||
|
after all, the @scheme[load] happens dynamically, while references to
|
||||||
|
identifiers within the module are resolved lexically, and therefore
|
||||||
|
statically.
|
||||||
|
|
||||||
|
Unlike @scheme[eval], @scheme[load] does not accept a namespace
|
||||||
|
argument. To supply a namespace to @scheme[load], set the
|
||||||
|
@scheme[current-namespace] parameter. The following example evaluates
|
||||||
|
the expressions in @filepath{here.scm} using the bindings of the
|
||||||
|
@schememodname[scheme/base] module:
|
||||||
|
|
||||||
|
@schememod[
|
||||||
|
scheme
|
||||||
|
|
||||||
|
(parameterize ([current-namespace (make-base-namespace)])
|
||||||
|
(load "here.scm"))
|
||||||
|
]
|
||||||
|
|
||||||
|
You can even use @scheme[namespace-anchor->namespace] to make the
|
||||||
|
bindings of the enclosing module accessible for dynamic evaluation. In
|
||||||
|
the following example, when @filepath{here.scm} is @scheme[load]ed, it
|
||||||
|
can refer to @scheme[there] as well as the bindings of
|
||||||
|
@schememodname[scheme]:
|
||||||
|
|
||||||
|
@schememod[
|
||||||
|
scheme
|
||||||
|
|
||||||
|
(define there "Utopia")
|
||||||
|
|
||||||
|
(define-namespace-anchor a)
|
||||||
|
(parameterize ([current-namespace (namespace-anchor->namespace a)])
|
||||||
|
(load "here.scm"))
|
||||||
|
]
|
||||||
|
|
||||||
|
Still, if @filepath{here.scm} defines any identifiers, the definitions
|
||||||
|
cannot be directly (i.e., statically) referenced by in the enclosing
|
||||||
|
module.
|
||||||
|
|
||||||
|
The @schememodname[scheme/load] module language is different from
|
||||||
|
@schememodname[scheme] or @schememodname[scheme/base]. A module using
|
||||||
|
@schememodname[scheme/load] treats all of its content as dynamic,
|
||||||
|
passing each form in the module body to @scheme[eval] (using a
|
||||||
|
namespace that is initialized with @schememodname[scheme]). As a
|
||||||
|
result, uses of @scheme[eval] and @scheme[load] in the module body see
|
||||||
|
the same dynamic namespace as immediate body forms. For example, if
|
||||||
|
@filepath{here.scm} contains
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(define here "Morporkia")
|
||||||
|
(define (go!) (set! here there))
|
||||||
|
]
|
||||||
|
|
||||||
|
then running
|
||||||
|
|
||||||
|
@schememod[
|
||||||
|
scheme/load
|
||||||
|
|
||||||
|
(define there "Utopia")
|
||||||
|
|
||||||
|
(load "here.scm")
|
||||||
|
|
||||||
|
(go!)
|
||||||
|
(printf "~a\n" here)
|
||||||
|
]
|
||||||
|
|
||||||
|
prints ``Utopia''.
|
||||||
|
|
||||||
|
Drawbacks of using @schememodname[scheme/load] include reduced
|
||||||
|
error checking, tool support, and performance. For example, with the
|
||||||
|
program
|
||||||
|
|
||||||
|
@schememod[
|
||||||
|
scheme/load
|
||||||
|
|
||||||
|
(define good 5)
|
||||||
|
(printf "running\n")
|
||||||
|
good
|
||||||
|
bad
|
||||||
|
]
|
||||||
|
|
||||||
|
DrScheme's @onscreen{Check Syntax} tool cannot tell that the second
|
||||||
|
@scheme[good] is a reference to the first, and the unbound reference
|
||||||
|
to @scheme[bad] is reported only at run time instead of rejected
|
||||||
|
syntactically.
|
||||||
|
|
|
@ -198,11 +198,11 @@ tempted to put just
|
||||||
(substring str 0 5))
|
(substring str 0 5))
|
||||||
]
|
]
|
||||||
|
|
||||||
into @filepath{piece.ss} and run @exec{mzscheme} with
|
into @filepath{piece.scm} and run @exec{mzscheme} with
|
||||||
|
|
||||||
@interaction[
|
@interaction[
|
||||||
#:eval piece-eval
|
#:eval piece-eval
|
||||||
(eval:alts (load "piece.ss") (void))
|
(eval:alts (load "piece.scm") (void))
|
||||||
(piece "howdy universe")
|
(piece "howdy universe")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user