
- added invoke-library syntax.ss, primdata.ss, 8.ms, root-experr*, libraries.stex, release_notes.stex - updated the date release_notes.stex - libraries contained within a whole program or library are now marked pending before their invoke code is run so that invoke cycles are reported as such rather than as attempts to invoke while still loading. compile.ss, syntax.ss, primdata.ss, 7.ms, root-experr* - the library manager now protects against unbound references from separately compiled libraries or programs to identifiers ostensibly but not actually exported by (invisible) libraries that exist only locally within a whole program. this is done by marking the invisibility of the library in the library-info and propagating it to libdesc records; the latter is checked upon library import, visit, and invoke as well as by verify-loadability. the import and visit code of each invisible no longer complains about invisibility since it shouldn't be reachable. syntax.ss, compile.ss, expand-lang.ss, 7.ms, 8.ms, root-experr*, patch* - documented that compile-whole-xxx's linearization of the library initialization code based on static dependencies might not work for dynamic dependencies. system.stex - optimized bignum right shifts so the code (1) doesn't look at shifted-off bigits if the bignum is positive, since it doesn't need to know in that case if any bits are set; (2) doesn't look at shifted-off bigits if the bignum is negative if it determines that at least one bit is set in the bits shifted off the low-order partially retained bigit; (3) quits looking, if it must look, for one bits as soon as it finds one; (4) looks from both ends under the assumption that set bits, if any, are most likely to be found toward the high or low end of the bignum rather than just in the middle; and (5) doesn't copy the retained bigits and then shift; rather shifts as it copies. This leads to dramatic improvements when the shift count is large and often significant improvements otherwise. number.c, 5_3.ms, release_notes.stex - threaded tc argument through to all calls to S_bignum and S_trunc_rem so they don't have to call get_thread_context() when it might already have been called. alloc.c, number.c, fasl.c, print.c, prim5.c, externs.h - added an expand-primitive handler to partially inline integer?. cpnanopass.ss - added some special cases for basic arithmetic operations (+, -, *, /, quotient, remainder, and the div/div0/mod/mod0 operations) to avoid doing unnecessary work for large bignums when the result will be zero (e.g,. multiplying by 0), the same as one of the inputs (e.g., adding 0 or multiplying by 1), or the additive inverse of one of the inputs (e.g., subtracting from 0, dividing by -1). This can have a major beneficial affect when operating on large bignums in the cases handled. also converted some uses of / into integer/ where going through the former would just add overhead without the possibility of optimization. 5_3.ss, number.c, externs.h, prim5.c, 5_3.ms, root-experr, patch*, release_notes.stex - added a queue to hold pending signals for which handlers have been registered via register-signal-handler so up to 63 (configurable in the source code) unhandled signals are buffered before the handler has to start dropping them. cmacros.ss, library.ss, prims.ss, primdata.ss, schsig.c, externs.h, prim5.c, thread.c, gc.c, unix.ms, system.stex, release_notes.stex - bytevector-compress now selects the level of compression based on the compress-level parameter. Prior to this it always used a default setting for compression. the compress-level parameter can now take on the new minimum in addition to low, medium, high, and maximum. minimum is presently treated the same as low except in the case of lz4 bytevector compression, where it results in the use of LZ4_compress_default rather than the slower but more effective LZ4_compress_HC. cmacros,ss, back.ss, compress_io.c, new_io.c, externs.h, bytevector.ms, mats/Mf-base, root-experr* io.stex, objects.stex, release_notes.stex original commit: 72d90e4c67849908da900d0b6249a1dedb5f8c7f
1220 lines
48 KiB
Plaintext
1220 lines
48 KiB
Plaintext
% Copyright 2005-2017 Cisco Systems, Inc.
|
|
%
|
|
% Licensed under the Apache License, Version 2.0 (the "License");
|
|
% you may not use this file except in compliance with the License.
|
|
% You may obtain a copy of the License at
|
|
%
|
|
% http://www.apache.org/licenses/LICENSE-2.0
|
|
%
|
|
% Unless required by applicable law or agreed to in writing, software
|
|
% distributed under the License is distributed on an "AS IS" BASIS,
|
|
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
% See the License for the specific language governing permissions and
|
|
% limitations under the License.
|
|
\chapter{Libraries and Top-level Programs\label{CHPTLIBRARIES}}
|
|
|
|
\index{libraries}%
|
|
\index{top-level-programs}%
|
|
The Revised$^6$ Report describes two units of portable code:
|
|
libraries and top-level programs.
|
|
A library is a named collection of bindings with a declared set of
|
|
explicitly exported bindings, a declared set of imported libraries, and a
|
|
body that initializes its bindings.
|
|
A top-level program is a stand-alone program with a declared set of
|
|
imported libraries and a body that is run when the top-level program is
|
|
run.
|
|
The bindings in a library are created and its initialization code run only
|
|
if the library is used, directly or indirectly, by a top-level program.
|
|
|
|
\index{\scheme{import}}%
|
|
The \scheme{import} declarations appearing within libraries and top-level
|
|
programs serve two purposes: first, they cause the imported libraries to
|
|
be loaded, and second, they cause the bindings of the imported libraries
|
|
to become visible in the importing library or top-level program.
|
|
Libraries are typically stored in the file system, with one library per
|
|
file, and the library name typically identifies the file-system path to
|
|
the library, possibly relative to a default or programmer-specified set of
|
|
library locations.
|
|
The exact mechanism by which top-level programs are run and libraries are
|
|
loaded is implementation-dependent.
|
|
|
|
This chapter describes the mechanisms by which libraries and programs are
|
|
loaded in {\ChezScheme} along with various features for controlling and
|
|
tracking this process.
|
|
It also describes the set of built-in libraries and syntactic forms for
|
|
defining new libraries and top-level programs outside of a library or
|
|
top-level program file.
|
|
|
|
% \section{Locating Libraries\label{SECTLOCATINGLIBRARIES}}
|
|
%
|
|
% In {\ChezScheme}, a library to be loaded implicitly by \scheme{import}
|
|
% must reside in a file whose name reflects the name of the library.
|
|
% For example, if the library's name is \scheme{(tools sorting)}, the
|
|
% base name of the file must be \scheme{sorting} with a valid extension, and
|
|
% the file must be in a directory named \scheme{tools} which itself resides
|
|
% in one of the directories searched by \scheme{import}.
|
|
% The set of directories searched by \scheme{import} is determined by
|
|
% the
|
|
% \index{\scheme{library-directories}}\scheme{library-directories}
|
|
% parameter, and the set of
|
|
% extensions is determined by the
|
|
% \index{\scheme{library-extensions}}\scheme{library-extensions}
|
|
% parameter.
|
|
% So, if \scheme{(library-directories)} contains the pathnames
|
|
% \scheme{"/usr/lib/scheme/libraries"} and \scheme{"."}, and
|
|
% \scheme{(library-extensions)} contains the extensions \scheme{.ss}
|
|
% and \scheme{.sls}, the path of the \scheme{(tools sorting)}
|
|
% library must be one of the following.
|
|
%
|
|
% \schemedisplay
|
|
% /usr/lib/scheme/libraries/tools/sorting.ss
|
|
% /usr/lib/scheme/libraries/tools/sorting.sls
|
|
% ./tools/sorting.ss
|
|
% ./tools/sorting.sls
|
|
% \endschemedisplay
|
|
%
|
|
% A file containing a library or set of libraries can be explicitly loaded
|
|
% via \scheme{load}, in which case the file may have any name and may reside
|
|
% anywhere in the file system.
|
|
%
|
|
% \index{\scheme{compile-library}}%
|
|
% \index{\scheme{compile-imported-libraries}}%
|
|
% A file containing a library may be compiled with \scheme{compile-file}
|
|
% or \scheme{compile-library}.
|
|
% The only difference between the two is that the latter treats the source
|
|
% file as if it were prefixed by an implicit \scheme{#!r6rs}.
|
|
% Any libraries upon which the library depends must be compiled first.
|
|
% This can be done manually or by setting the parameter
|
|
% \scheme{compile-imported-libraries} to \scheme{#t} before compiling
|
|
% the importing library.
|
|
% If one of the libraries imported by the library is subsequently
|
|
% recompiled (say because it was modified), the importing library must also
|
|
% be recompiled.
|
|
|
|
|
|
\section{Built-in Libraries\label{SECTBUILTINLIBRARIES}}
|
|
|
|
In addition to the RNRS libraries mandated by the Revised$^6$ Report:
|
|
|
|
\schemedisplay
|
|
(rnrs base (6))
|
|
(rnrs arithmetic bitwise (6))
|
|
(rnrs arithmetic fixnums (6))
|
|
(rnrs arithmetic flonums (6))
|
|
(rnrs bytevectors (6))
|
|
(rnrs conditions (6))
|
|
(rnrs control (6))
|
|
(rnrs enums (6))
|
|
(rnrs eval (6))
|
|
(rnrs exceptions (6))
|
|
(rnrs files (6))
|
|
(rnrs hashtables (6))
|
|
(rnrs io ports (6))
|
|
(rnrs io simple (6))
|
|
(rnrs lists (6))
|
|
(rnrs mutable-pairs (6))
|
|
(rnrs mutable-strings (6))
|
|
(rnrs programs (6))
|
|
(rnrs r5rs (6))
|
|
(rnrs records procedural (6))
|
|
(rnrs records syntactic (6))
|
|
(rnrs records inspection (6))
|
|
(rnrs sorting (6))
|
|
(rnrs syntax-case (6))
|
|
(rnrs unicode (6))
|
|
\endschemedisplay
|
|
|
|
\index{\scheme{(chezscheme)} library}%
|
|
\index{\scheme{(chezscheme csv7)} library}%
|
|
\index{\scheme{(scheme)} library}%
|
|
\index{\scheme{(scheme csv7)} library}%
|
|
{\ChezScheme} also provides two additional libraries: \scheme{(chezscheme)}
|
|
and \scheme{(chezscheme csv7)}.
|
|
The former can also be referenced as \scheme{(scheme)} and the latter can
|
|
also be referenced as \scheme{(scheme csv7)}.
|
|
|
|
The \scheme{(chezscheme)} library exports bindings for every identifier whose
|
|
binding is described in this document, including those for keywords like
|
|
\scheme{lambda}, auxiliary keywords like \scheme{else}, module names
|
|
like \scheme{scheme}, and procedure names like \scheme{cons}.
|
|
In most cases where an identifier exported from the
|
|
\scheme{(chezscheme)} library corresponds to an identifier exported from
|
|
one of the RNRS libraries, the bindings are identical.
|
|
In some cases, however, the \scheme{(chezscheme)} bindings extend the
|
|
\scheme{rnrs} bindings in some way.
|
|
For example, the \scheme{(chezscheme)} \scheme{syntax-rules} form allows
|
|
its clauses to have fenders (Section~\ref{SECTSYNTAXRULES}), while the
|
|
\scheme{(rnrs)} \scheme{syntax-rules} form does not.
|
|
Similarly, the \scheme{(chezscheme)} \scheme{current-input-port} procedure
|
|
accepts an optional \var{port} argument that, when specified, sets the
|
|
current input port to \var{port} (Section~\ref{SECTIOINPUT}), while the
|
|
\scheme{(rnrs)} \scheme{current-input-port} procedure does not.
|
|
When the \scheme{(chezscheme)} library extends an RNRS binding in some
|
|
way, the \scheme{(chezscheme)} library also exports the RNRS version,
|
|
with the name prefixed by \scheme{r6rs:}, e.g., \scheme{r6rs:syntax-rules}
|
|
or \scheme{r6rs:current-input-port}.
|
|
|
|
The \scheme{(chezscheme csv7)} Version~7 backward compatibility library
|
|
contains bindings for a set of syntactic forms and procedures whose syntax
|
|
or semantics directly conflicts with the RNRS bindings for the same
|
|
identifiers.
|
|
The following identifiers are exported from \scheme{(chezscheme csv7)}.
|
|
|
|
\schemedisplay
|
|
record-field-accessible?
|
|
record-field-accessor
|
|
record-field-mutable?
|
|
record-field-mutator
|
|
record-type-descriptor
|
|
record-type-field-decls
|
|
record-type-field-names
|
|
record-type-name
|
|
record-type-symbol
|
|
\endschemedisplay
|
|
|
|
The bindings of this library should be used only for old code; new
|
|
code should use the RNRS variants.
|
|
Each of these is also available in the \scheme{(chezscheme)} library with
|
|
the prefix \scheme{csv7:}, e.g., \scheme{csv7:record-type-name}.
|
|
|
|
The interaction environment in which code outside of a library or
|
|
RNRS top-level program is scoped contains all of the bindings of the
|
|
\scheme{(chezscheme)} library, as described in
|
|
Section~\ref{SECTUSEINTERACTIONENVIRONMENT}.
|
|
|
|
|
|
\section{Running Top-level Programs\label{SECTRUNNINGTOPLEVELPROGRAMS}}
|
|
|
|
\index{\scheme{scheme-script}}%
|
|
\index{\scheme{--program} command-line option}%
|
|
\index{\scheme{load-program}}%
|
|
A top-level program must reside in its own file, which may have any
|
|
name and may reside anywhere in the file system.
|
|
A top-level program residing in a file is run by one of three mechanisms:
|
|
the \scheme{scheme-script} command, the \scheme{--program} command-line
|
|
argument, or the \scheme{load-program} procedure.
|
|
|
|
The \scheme{scheme-script} command is used as follows:
|
|
|
|
\schemedisplay
|
|
scheme-script \var{program-filename} \var{arg} \dots
|
|
\endschemedisplay
|
|
|
|
It may also be run implicitly on Unix-based systems by placing the line
|
|
|
|
\schemedisplay
|
|
#! /usr/bin/env scheme-script
|
|
\endschemedisplay
|
|
|
|
at the front of the file containing the top-level program, making the
|
|
top-level program file executable, and executing the file.
|
|
This line may be replaced with
|
|
|
|
\schemedisplay
|
|
#! /usr/bin/scheme-script
|
|
\endschemedisplay
|
|
|
|
with \scheme{/usr/bin} replaced by the absolute path to the directory
|
|
containing \scheme{scheme-script} if it is not in \scheme{/usr/bin}.
|
|
The first form is recommended in the nonnormative appendices to the
|
|
Revised$^6$ Report~\cite{r6rsapps}, and works wherever
|
|
\scheme{scheme-script} appears in the path.
|
|
|
|
The \scheme{--program} command is used similarly with the \scheme{scheme}
|
|
or \scheme{petite} executables, either by running:
|
|
|
|
\schemedisplay
|
|
scheme --program \var{program-filename} \var{arg} \dots
|
|
petite --program \var{program-filename} \var{arg} \dots
|
|
\endschemedisplay
|
|
|
|
or by including
|
|
|
|
\schemedisplay
|
|
#! /usr/bin/scheme --script
|
|
\endschemedisplay
|
|
|
|
or
|
|
|
|
\schemedisplay
|
|
#! /usr/bin/petite --script
|
|
\endschemedisplay
|
|
|
|
at the front of the top-level program file, making the file executable,
|
|
and executing the file.
|
|
Again, \scheme{/usr/bin} should be replaced with the absolute path to
|
|
the actual directory in which \scheme{scheme} and/or \scheme{petite}
|
|
resides, if not \scheme{/usr/bin}.
|
|
|
|
The \scheme{load-program} procedure, described in
|
|
Section~\ref{SECTMISCCOMPILEEVAL}, is used like \scheme{load}:
|
|
|
|
\schemedisplay
|
|
(load-program \var{string})
|
|
\endschemedisplay
|
|
|
|
where \var{string} names the file in which the top-level program resides.
|
|
|
|
Regardless of the mechanism used, if the opening line is in one of the
|
|
forms described above, or more generally, consists of
|
|
\scheme{#!} followed by a space or a forward slash, the opening line
|
|
is not considered part of the program and is ignored once the Scheme
|
|
system starts up and begins to run the program.
|
|
Thus, the line may be present even in a file loaded by \scheme{load-program}.
|
|
In fact, \scheme{load-program} is ultimately used by the other two
|
|
mechanisms described above, via the value of the \scheme{scheme-program}
|
|
parameter described in Section~\ref{SECTMISCWAITERS}, and it is
|
|
\scheme{load-program} that scans past the \scheme{#!} line, if present,
|
|
before evaluating the program.
|
|
|
|
A top-level program may be compiled with the
|
|
\index{\scheme{compile-program}}\scheme{compile-program}
|
|
procedure described in Section~\ref{SECTMISCCOMPILEEVAL}.
|
|
\scheme{compile-program} copies the \scheme{#!} line from the source
|
|
file to the object file, followed by a compiled version of the source
|
|
code.
|
|
Any libraries upon which the top-level program depends, other than
|
|
built-in libraries, must be compiled first via \scheme{compile-file}
|
|
or \scheme{compile-library}.
|
|
This can be done manually or by setting the parameter
|
|
\scheme{compile-imported-libraries} to \scheme{#t} before compiling
|
|
the program.
|
|
The program must be recompiled if any of the libraries upon which
|
|
it depends are recompiled.
|
|
A compiled top-level program can be run just like a source top-level
|
|
program via each of the mechanisms described above.
|
|
|
|
\index{\scheme{load-library}}%
|
|
In {\ChezScheme}, a library may also be defined in the REPL or placed in a
|
|
file to be loaded via \scheme{load} or \scheme{load-library}.
|
|
The syntax for a library is the same whether the library is placed in
|
|
its own file and implicitly loaded via \scheme{import}, entered into
|
|
the REPL, or placed in a file along with other top-level expressions to
|
|
be evaluated by \scheme{load}.
|
|
A top-level program may also be defined in the REPL or placed in a file
|
|
to be loaded via \scheme{load}, but in this case, the syntax is slightly
|
|
different.
|
|
In the language of the Revised$^6$ Report, a top-level program is merely
|
|
an unwrapped sequence of subforms consisting of an \scheme{import} form
|
|
and a body, delimited only by the boundaries of the file in which it
|
|
resides.
|
|
In order for a top-level program to be entered in the REPL or placed in
|
|
a file to be evaluated by \scheme{load}, {\ChezScheme} allows top-level
|
|
programs to be enclosed in a
|
|
\index{\scheme{top-level-program}}\scheme{top-level-program} form.
|
|
|
|
\section{Library and Top-level Program Forms\label{SECTLIBRARYFORMS}}
|
|
|
|
%----------------------------------------------------------------------------
|
|
\noskipentryheader
|
|
\formdef{library}{\categorysyntax}{(library \var{name} \var{exports} \var{imports} \var{library-body})}
|
|
\returns unspecified
|
|
\listlibraries
|
|
\endnoskipentryheader
|
|
|
|
The \scheme{library} form defines a new library with the specified
|
|
name, exports, imports, and body.
|
|
Details on the syntax and semantics of the library form are given in
|
|
Section~\ref{TSPL:SECTLIBPROGRAMS} of {\TSPLFOUR} and in the Revised$^6$
|
|
Report.
|
|
|
|
Only one version of a library can be loaded at any given time, and an
|
|
exception is raised if a library is implicitly loaded via \scheme{import}
|
|
when another version of the library has already been loaded.
|
|
{\ChezScheme} permits a different version of the library, or a new
|
|
instance of the same version, to be entered explicitly into the REPL
|
|
or loaded explicitly from a file, to facilitate interactive testing
|
|
and debugging.
|
|
The programmer should take care to make sure that any code that uses
|
|
the library is also reentered or reloaded, to make sure that code
|
|
accesses the bindings of the new instance of the library.
|
|
|
|
\schemedisplay
|
|
(library (test (1)) (export x) (import (rnrs)) (define x 3))
|
|
(import (test))
|
|
(define f (lambda () x))
|
|
(f) ;=> 3
|
|
|
|
(library (test (1)) (export x) (import (rnrs)) (define x 4))
|
|
(import (test))
|
|
(f) ;=> 3 ; oops---forgot to redefine f
|
|
(define f (lambda () x))
|
|
(f) ;=> 4
|
|
|
|
(library (test (2)) (export x) (import (rnrs)) (define x 5))
|
|
(import (test))
|
|
(define f (lambda () x))
|
|
(f) ;=> 5
|
|
\endschemedisplay
|
|
|
|
As with module imports (Section~\ref{SECTSYNTAXMODULES}), a library
|
|
\scheme{import} may appear anywhere a definition may appear, including at
|
|
top level in the REPL, in a file to be loaded by \scheme{load}, or within
|
|
a \scheme{lambda}, \scheme{let}, \scheme{letrec}, \scheme{letrec*},
|
|
etc., body.
|
|
The same \scheme{import} form may be used to import from both libraries
|
|
and modules.
|
|
|
|
\schemedisplay
|
|
(library (foo) (export a) (import (rnrs)) (define a 'a-from-foo))
|
|
(module bar (b) (define b 'b-from-bar))
|
|
(let () (import (foo) bar) (list a b)) ;=> (a-from-foo b-from-bar)
|
|
\endschemedisplay
|
|
|
|
The \scheme{import} keyword is not visible within a library body
|
|
unless the library imports it from the \scheme{(chezscheme)} library.
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{top-level-program}{\categorysyntax}{(top-level-program \var{imports} \var{body})}
|
|
\returns unspecified
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
\index{top-level-programs}%
|
|
A \scheme{top-level-program} form may be entered into the REPL or placed
|
|
in a file to be loaded via \scheme{load}, where it behaves as if its
|
|
subforms were placed in a file and loaded via \scheme{load-program}.
|
|
Details on the syntax and semantics of a top-level program are given in
|
|
Section~\ref{TSPL:SECTLIBPROGRAMS} of {\TSPLFOUR} and in the Revised$^6$
|
|
Report.
|
|
|
|
The following transcript illustrates a \scheme{top-level-program} being
|
|
tested in the REPL.
|
|
|
|
\schemedisplay
|
|
> (top-level-program (import (rnrs))
|
|
(display "hello!\n"))
|
|
hello!
|
|
\endschemedisplay
|
|
|
|
\section{Standalone import and export forms\label{SECTLIBRARYIMPORTEXPORTFORMS}}
|
|
|
|
Although not required by the Revised$^6$ Report,
|
|
{\ChezScheme} supports the use of standalone import and
|
|
export forms.
|
|
The import forms can appear anywhere other definitions
|
|
can appear, including within a \scheme{library} body,
|
|
\scheme{module} (Section~\ref{SECTSYNTAXMODULES}) body,
|
|
\scheme{lambda} or other local body, and at top level.
|
|
The export forms can appear within the definitions of a
|
|
\scheme{library} or \scheme{module} body to specify additional
|
|
exports for the library or module.
|
|
|
|
Within a library or top-level program, the keywords for
|
|
these forms must be imported from the \scheme{(chezscheme)}
|
|
library to be available for use, since they are not
|
|
defined in any of the Revised$^6$ Report libraries.
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{import}{\categorysyntax}{(import \var{import-spec} \dots)}
|
|
\formdef{import-only}{\categorysyntax}{(import-only \var{import-spec} \dots)}
|
|
\returns unspecified
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
An \scheme{import} or \scheme{import-only} form is a definition and can
|
|
appear anywhere other definitions can appear, including
|
|
at the top level of a program, nested within the bodies of
|
|
\scheme{lambda} expressions, and nested within modules
|
|
and libraries.
|
|
|
|
Each \var{import-spec} must take one of the following forms.
|
|
|
|
\schemedisplay
|
|
\var{import-set}
|
|
(for \var{import-set} \var{import-level} \dots)
|
|
\endschemedisplay
|
|
|
|
\noindent
|
|
The \scheme{for} wrapper and \var{import-level} are described in
|
|
Chapter~\ref{TSPL:CHPTLIBRARIES} of {\TSPLFOUR}.
|
|
They are ignored by {\ChezScheme}, which determines
|
|
automatically the levels at which identifiers must
|
|
be imported, as permitted by the Revised$^6$ Report.
|
|
This frees the programmer from the obligation
|
|
to do so and results in more generality as well as more
|
|
precision in the set of libraries actually imported
|
|
at compile and run time~\cite{Ghuloum:libraries,Ghuloum:phd}.
|
|
|
|
An \var{import-set} must take one of the following forms:
|
|
|
|
\schemedisplay
|
|
\var{library-spec}
|
|
\var{module-name}
|
|
(only \var{import-set} \var{identifier} \dots)
|
|
(except \var{import-set} \var{identifier} \dots)
|
|
(prefix \var{import-set} \var{prefix})
|
|
(add-prefix \var{import-set} \var{prefix})
|
|
(drop-prefix \var{import-set} \var{prefix})
|
|
(rename \var{import-set} (\var{import-name} \var{internal-name}) \dots)
|
|
(alias \var{import-set} (\var{import-name} \var{internal-name}) \dots)
|
|
\endschemedisplay
|
|
|
|
Several of these are specified by the Revised$^6$ Report; the remainder
|
|
are {\ChezScheme} extensions, including \var{module-name} and the
|
|
\scheme{add-prefix}, \scheme{drop-prefix}, and \scheme{alias} forms.
|
|
|
|
An \scheme{import} or \scheme{import-only} form makes the specified bindings
|
|
visible in the scope in which they appear.
|
|
Except at top level, they differ in that \scheme{import} leaves all bindings
|
|
except for those shadowed by the imported names visible, whereas \scheme{import-only}
|
|
hides all existing bindings, i.e., makes only the imported names visible.
|
|
At top level, \scheme{import-only} behaves like \scheme{import}.
|
|
|
|
Each \var{import-set} identifies a set of names to make visible
|
|
as follows.
|
|
|
|
\begin{description}
|
|
\item[\scheme{\var{library-spec}}:]
|
|
all exports of the library identified by the Revised$^6$ Report \var{library-spec}
|
|
(Chapter~\ref{TSPL:CHPTLIBRARIES}).
|
|
|
|
\item[\scheme{\var{module-name}}:]
|
|
all exports of module named by the identifier \var{module-name}
|
|
|
|
\item[\scheme{(only \var{import-set} \var{identifier} \dots)}:]
|
|
of those specified by \var{import-set}, just \scheme{\var{identifier} \dots}
|
|
|
|
\item[\scheme{(except \var{import-set} \var{identifier} \dots)}:]
|
|
all specified by \var{import-set} except \scheme{\var{identifier} \dots}
|
|
|
|
\item[\scheme{(prefix \var{import-set} \var{prefix})}:]
|
|
all specified by \var{import-set}, each prefixed by \var{prefix}
|
|
|
|
\item[\scheme{(add-prefix \var{import-set} \var{prefix})}:]
|
|
all specified by \var{import-set}, each prefixed by \var{prefix}
|
|
(just like \scheme{prefix})
|
|
|
|
\item[\scheme{(drop-prefix \var{import-set} \var{prefix})}:]
|
|
all specified by \var{import-set}, with prefix \var{prefix} removed
|
|
|
|
\item[\scheme{(rename \var{import-set} (\var{import-name} \var{internal-name}) \dots)}:]
|
|
all specified by \var{import-set}, with each identifier \var{import-name}
|
|
renamed to the corresponding identifier \var{internal-name}
|
|
|
|
\item[\scheme{(alias \var{import-set} (\var{import-name} \var{internal-name}) \dots)}:]
|
|
all specified by \var{import-set}, with each \var{internal-name} as an alias
|
|
for \var{import-name}
|
|
\end{description}
|
|
|
|
The \scheme{alias} form differs from the \scheme{rename} form in that both
|
|
\var{import-name} and \var{internal-name} are in the resulting set,
|
|
rather than just \var{internal-name}.
|
|
|
|
It is a syntax violation if the
|
|
given selection or transformation cannot be made because of a missing
|
|
export or prefix.
|
|
|
|
An identifier made visible via an import of a module or library is scoped as if its
|
|
definition appears where the import occurs.
|
|
The following example illustrates these scoping rules, using a local
|
|
module \scheme{m}.
|
|
|
|
\schemedisplay
|
|
(library (A) (export x) (import (rnrs)) (define x 0))
|
|
(let ([x 1])
|
|
(module m (x setter)
|
|
(define-syntax x (identifier-syntax z))
|
|
(define setter (lambda (x) (set! z x)))
|
|
(define z 2))
|
|
(let ([y x] [z 3])
|
|
(import m (prefix (A) a:))
|
|
(setter 4)
|
|
(list x a:x y z))) ;=> (4 0 1 3)
|
|
\endschemedisplay
|
|
|
|
\noindent
|
|
The inner \scheme{let} expression binds \scheme{y} to the value of
|
|
the \scheme{x} bound by the outer \scheme{let}.
|
|
The import of \scheme{m} makes the definitions of \scheme{x}
|
|
and \scheme{setter} visible within the inner \scheme{let}.
|
|
The import of \scheme{(A)} makes the variable \scheme{x} exported
|
|
from \scheme{(A)} visible as \scheme{a:x} within the body of the
|
|
inner \scheme{let}.
|
|
Thus, in the expression \scheme{(list x a:x y z)}, \scheme{x} refers to the
|
|
identifier macro exported from \scheme{m} while \scheme{a:x} refers to the
|
|
variable \scheme{x} exported from \scheme{(A)} and \scheme{y} and \scheme{z}
|
|
refer to the bindings established by the inner \scheme{let}.
|
|
The identifier macro \scheme{x} expands into a reference to
|
|
the variable \scheme{z} defined within the module.
|
|
|
|
With local import forms, it is rarely necessary to use the extended
|
|
import specifiers.
|
|
For example, an abstraction that encapsulates the import and reference
|
|
can easily be defined and used as follows.
|
|
|
|
\schemedisplay
|
|
(define-syntax from
|
|
(syntax-rules ()
|
|
[(_ m id) (let () (import-only m) id)]))
|
|
|
|
(library (A) (export x) (import (rnrs)) (define x 1))
|
|
(let ([x 10])
|
|
(module M (x) (define x 2))
|
|
(cons (from (A) x) (from M x))) ;=> (1 . 2)
|
|
\endschemedisplay
|
|
|
|
\noindent
|
|
The definition of \scheme{from} could use \scheme{import} rather than
|
|
\scheme{import-only}, but by using \scheme{import-only} we get feedback
|
|
if an attempt is made to import an identifier from a library or
|
|
module that does not export the identifier.
|
|
With \scheme{import} instead of \scheme{import-only}, the current binding,
|
|
if any, would be visible if the library or module does not export the
|
|
specified name.
|
|
|
|
\schemedisplay
|
|
(define-syntax lax-from
|
|
(syntax-rules ()
|
|
[(_ m id) (let () (import m) id)]))
|
|
|
|
(library (A) (export x) (import (rnrs)) (define x 1))
|
|
|
|
(let ([x 10])
|
|
(module M (x) (define x 2))
|
|
(+ (from (A) x) (from M y))) ;=> \var{exception: unbound identifier y}
|
|
|
|
(let ([x 10] [y 20])
|
|
(module M (x) (define x 2))
|
|
(+ (lax-from (A) x) (lax-from M y))) ;=> 21
|
|
\endschemedisplay
|
|
|
|
Import visibility interacts with hygienic macro expansion in such a
|
|
way that, as one might expect,
|
|
an identifier \var{x} imported from a module \var{M} is treated in
|
|
the importing context as if the corresponding export identifier had
|
|
been present in the import form along with \var{M}.
|
|
|
|
The \scheme{from} abstraction above works because both \var{M} and \var{id}
|
|
appear in the input to the abstraction, so the imported \var{id} captures
|
|
the reference to \var{id}.
|
|
|
|
The following variant of \var{from} also works, because both names are
|
|
introduced into the output by the transformer.
|
|
|
|
\schemedisplay
|
|
(module M (x) (define x 'x-of-M))
|
|
(define-syntax x-from-M
|
|
(syntax-rules ()
|
|
[(_) (let () (import M) x)]))
|
|
|
|
(let ([x 'local-x]) (x-from-M)) ;=> x-of-M
|
|
\endschemedisplay
|
|
|
|
On the other hand, imports of introduced module names do not capture
|
|
free references.
|
|
|
|
\schemedisplay
|
|
(let ([x 'local-x])
|
|
(define-syntax alpha
|
|
(syntax-rules ()
|
|
[(_ var) (let () (import M) (list x var))]))
|
|
|
|
(alpha x)) ;=> (x-of-M local-x)
|
|
\endschemedisplay
|
|
|
|
Similarly, imports from free module names do not capture references
|
|
to introduced variables.
|
|
|
|
\schemedisplay
|
|
(let ([x 'local-x])
|
|
(define-syntax beta
|
|
(syntax-rules ()
|
|
[(_ m var) (let () (import m) (list x var))]))
|
|
|
|
(beta M x)) ;=> (local-x x-of-M)
|
|
\endschemedisplay
|
|
|
|
This semantics extends to prefixed, renamed, and aliased bindings
|
|
created by the extended \scheme{import} specifiers \scheme{prefix},
|
|
\scheme{rename}, and \scheme{alias}.
|
|
|
|
The \scheme{from} abstraction
|
|
works for variables but not for exported keywords, record names,
|
|
or module names, since the output is an expression and may thus appear only where
|
|
expressions may appear.
|
|
A generalization of this technique is used in the following definition
|
|
of \scheme{import*}, which supports renaming of imported bindings and
|
|
selective import of specific bindings---without the use of the built-in
|
|
\scheme{import} subforms for selecting and renaming identifiers
|
|
|
|
\schemedisplay
|
|
(define-syntax import*
|
|
(syntax-rules ()
|
|
[(_ m) (begin)]
|
|
[(_ m (new old))
|
|
(module (new)
|
|
(module (tmp)
|
|
(import m)
|
|
(alias tmp old))
|
|
(alias new tmp))]
|
|
[(_ m id) (module (id) (import m))]
|
|
[(_ m spec0 spec1 ...)
|
|
(begin (import* m spec0) (import* m spec1 ...))]))
|
|
\endschemedisplay
|
|
|
|
\noindent
|
|
To selectively import an identifier from module or library \scheme{m}, the
|
|
\scheme{import*} form expands into an anonymous module that first
|
|
imports all exports of \scheme{m} then re-exports only the selected
|
|
identifier.
|
|
To rename on import the macro expands into an anonymous module that
|
|
instead exports an alias (Section~\ref{SECTSYNTAXALIAS}) bound to the new name.
|
|
|
|
If the output placed the definition of \scheme{new} in the same
|
|
scope as the import of \scheme{m}, a naming conflict would arise
|
|
whenever \scheme{new} is also present in the interface
|
|
of \scheme{m}.
|
|
To prevent this, the output instead places the import within a nested
|
|
anonymous module and links \scheme{old} and \scheme{new}
|
|
by means of an alias for the introduced identifier \scheme{tmp}.
|
|
|
|
The macro expands recursively to handle multiple import specifications.
|
|
Each of the following examples imports \scheme{cons} as \scheme{+} and \scheme{+} as
|
|
\scheme{cons}, which is probably not a very good idea.
|
|
|
|
\schemedisplay
|
|
(let ()
|
|
(import* scheme (+ cons) (cons +))
|
|
(+ (cons 1 2) (cons 3 4))) ;=> (3 . 7)
|
|
|
|
(let ()
|
|
(import* (rnrs) (+ cons) (cons +))
|
|
(+ (cons 1 2) (cons 3 4))) ;=> (3 . 7)
|
|
\endschemedisplay
|
|
|
|
% for testing
|
|
% (module m (x y z)
|
|
% (define x 'x)
|
|
% (define y 'y)
|
|
% (define z 'z))
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{export}{\categorysyntax}{(export \var{export-spec} \dots)}
|
|
\returns unspecified
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
An \scheme{export} form is a definition and can appear with other
|
|
definitions at the front of a \scheme{library} or \scheme{module}.
|
|
It is a syntax error for an \scheme{export} form to appear in other
|
|
contexts, including at top level or among the definitions of a
|
|
top-level program or \scheme{lambda} body.
|
|
|
|
Each \var{export-spec} must take one of the following forms.
|
|
|
|
\schemedisplay
|
|
\var{identifier}
|
|
(rename (\var{internal-name} \var{export-name}) \dots)
|
|
(import \var{import-spec} \dots)
|
|
\endschemedisplay
|
|
|
|
\noindent
|
|
where each \var{internal-name} and \var{export-name} is an identifier.
|
|
The first two are syntactically identical to \scheme{library}
|
|
\var{export-spec}s, while the third is syntactically
|
|
identical to a {\ChezScheme} \scheme{import} form, which is an extension of the
|
|
R6RS library \scheme{import} subform.
|
|
The first form names a single export, \var{identifier}, whose export
|
|
name is the same as its internal name.
|
|
The second names a set of exports, each of whose export name is
|
|
given explicitly and may differ from its internal name.
|
|
|
|
For the third, the identifiers identified by the \scheme{import} form
|
|
become exports, with aliasing, renaming, prefixing, etc., as specified by the
|
|
\var{import-spec}s.
|
|
The module or library whose bindings are exported by an \scheme{import}
|
|
form appearing within an \scheme{export} form can
|
|
be defined within or outside the exporting module or library and need
|
|
not be imported elsewhere within the exporting module or library.
|
|
|
|
The following library exports a two-armed-only variant of \scheme{if}
|
|
along with all remaining bindings of the \scheme{(rnrs)} library.
|
|
|
|
\schemedisplay
|
|
(library (rnrs-no-one-armed-if) (export) (import (except (chezscheme) if))
|
|
(export if (import (except (rnrs) if)))
|
|
(define-syntax if
|
|
(let ()
|
|
(import (only (rnrs) if))
|
|
(syntax-rules ()
|
|
[(_ tst thn els) (if tst thn els)]))))
|
|
|
|
(import (rnrs-no-one-armed-if))
|
|
(if #t 3 4) ;=> 3
|
|
(if #t 3) ;=> \var{exception: invalid syntax}
|
|
\endschemedisplay
|
|
|
|
Another way to define the same library would be to define the
|
|
two-armed-only \scheme{if} with a different internal name and use
|
|
\scheme{rename} to export it under the name \scheme{if}:
|
|
|
|
\schemedisplay
|
|
(library (rnrs-no-one-armed-if) (export) (import (chezscheme))
|
|
(export (rename (two-armed-if if)) (import (except (rnrs) if)))
|
|
(define-syntax two-armed-if
|
|
(syntax-rules ()
|
|
[(_ tst thn els) (if tst thn els)])))
|
|
|
|
(import (rnrs-no-one-armed-if))
|
|
(if #t 3 4) ;=> 3
|
|
(if #t 3) ;=> \var{exception: invalid syntax}
|
|
\endschemedisplay
|
|
|
|
The placement of the \scheme{export} form in the library body is
|
|
irrelevant, e.g., the \scheme{export} form can appear after the
|
|
definition in the examples above.
|
|
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{indirect-export}{\categorysyntax}{(indirect-export \var{id} \var{indirect-id} \dots)}
|
|
\returns unspecified
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
This form is a definition and can appear wherever any other definition
|
|
can appear.
|
|
|
|
An \scheme{indirect-export} form declares that the named
|
|
\var{indirect-id}s are indirectly exported to top level if \var{id}
|
|
is exported to top level.
|
|
|
|
In general, if an identifier is not directly exported by a library or
|
|
module, it can be referenced outside of the library or module only in
|
|
the expansion of a macro defined within and exported from the library
|
|
or module.
|
|
Even this cannot occur for libraries or modules defined at top level
|
|
(or nested within other libraries or modules), unless either (1)
|
|
the library or module has been set up to implicitly export all
|
|
identifiers as indirect exports, or (2) each indirectly exported
|
|
identifier is explicitly declared as an indirect export of some
|
|
other identifier that is exported, either directly or indirectly, from
|
|
the library or module, via an \scheme{indirect-export} or the built-in
|
|
indirect export feature of a \scheme{module} export subform.
|
|
By default, (1) is true for a library and false for a module, but the
|
|
default can be overridden via the \scheme{implicit-exports}
|
|
form, which is described below.
|
|
|
|
This form is meaningful only within a top-level library, top-level module,
|
|
or module enclosed within a library or top-level module, although it
|
|
has no effect if the library or module already implicitly exports all
|
|
bindings.
|
|
It is allowed anywhere else definitions can appear, however, so macros
|
|
that expand into indirect export forms can be used in any definition
|
|
context.
|
|
|
|
Indirect exports are listed so the compiler can determine the
|
|
exact set of bindings (direct and indirect) that must be inserted
|
|
into the top-level environment, and conversely, the set of bindings
|
|
that may be treated more efficiently as local bindings (and
|
|
perhaps discarded, if they are not used).
|
|
|
|
In the example below, \scheme{indirect-export} is used to indirectly
|
|
export \scheme{count} to top level when \scheme{current-count} is
|
|
exported to top level.
|
|
|
|
\schemedisplay
|
|
(module M (bump-count current-count)
|
|
(define-syntax current-count (identifier-syntax count))
|
|
(indirect-export current-count count)
|
|
(define count 0)
|
|
(define bump-count
|
|
(lambda ()
|
|
(set! count (+ count 1)))))
|
|
|
|
(import M)
|
|
(bump-count)
|
|
current-count ;=> 1
|
|
count ;=> \var{exception: unbound identifier count}
|
|
\endschemedisplay
|
|
|
|
An \scheme{indirect-export} form is not required to make \scheme{count}
|
|
visible for \scheme{bump-count}, since it is a procedure whose code
|
|
is contained within the module rather than a macro that might expand
|
|
into a reference to \scheme{count} somewhere outside the module.
|
|
|
|
It is often useful to use \scheme{indirect-export} in the output
|
|
of a macro that expands into another macro named \var{a} if
|
|
\var{a} expands into references to identifiers that might not
|
|
be directly exported, as illustrated by the alternative definition
|
|
of module \scheme{M} above.
|
|
|
|
\schemedisplay
|
|
(define-syntax define-counter
|
|
(syntax-rules ()
|
|
[(_ getter bumper init incr)
|
|
(begin
|
|
(define count init)
|
|
(define-syntax getter (identifier-syntax count))
|
|
(indirect-export getter count)
|
|
(define bumper
|
|
(lambda ()
|
|
(set! count (incr count)))))]))
|
|
|
|
(module M (bump-count current-count)
|
|
(define-counter current-count bump-count 0 add1))
|
|
\endschemedisplay
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{implicit-exports}{\categorysyntax}{(implicit-exports #t)}
|
|
\formdef{implicit-exports}{\categorysyntax}{(implicit-exports #f)}
|
|
\returns unspecified
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
An \scheme{implicit-exports} form is a definition and can appear with other
|
|
definitions at the front of a \scheme{library} or \scheme{module}.
|
|
It is a syntax error for an \scheme{implicit-exports} form to appear in other
|
|
contexts, including at top level or among the definitions of a
|
|
top-level program or \scheme{lambda} body.
|
|
|
|
The \scheme{implicit-exports} form determines whether identifiers
|
|
not directly exported from a module or library are automatically
|
|
indirectly exported to the top level if any meta-binding (keyword, meta
|
|
definition, or property definition) is directly exported to top level
|
|
from the library or module.
|
|
The default for libraries is \scheme{#t}, to match the behavior required
|
|
by the Revised$^6$ Report, while the default for modules is \scheme{#f}.
|
|
The \scheme{implicit-exports} form is meaningful only within a library,
|
|
top-level module, or module enclosed within a library or top-level module.
|
|
It is allowed in a module enclosed within a \scheme{lambda}, \scheme{let},
|
|
or similar body, but ignored there because none of that module's bindings
|
|
can be exported to top level.
|
|
|
|
The advantage of \scheme{(implicit-exports #t)} is that indirect exports
|
|
need not be listed explicitly, which is convenient.
|
|
A disadvantage is that it often results in more bindings than necessary
|
|
being elevated to top level where they cannot be discarded as useless
|
|
by the optimizer.
|
|
For modules, another disadvantage is such bindings
|
|
cannot be proven immutable, which inhibits important optimizations such
|
|
as procedure inlining.
|
|
This can result in significantly lower run-time performance.
|
|
|
|
\section{Explicitly invoking libraries\label{SECTLIBRARYINVOCATION}}
|
|
|
|
%----------------------------------------------------------------------------
|
|
\noskipentryheader
|
|
\formdef{invoke-library}{\categoryprocedure}{(invoke-library \var{libref})}
|
|
\returns unspecified
|
|
\listlibraries
|
|
\endnoskipentryheader
|
|
|
|
\var{libref} must be an s-expression in the form of a library reference.
|
|
The syntax for library references is given in
|
|
Chapter~\ref{TSPL:CHPTLIBRARIES} of {\TSPLFOUR} and in the Revised$^6$
|
|
Report.
|
|
|
|
A library is implicitly invoked when or before some expression
|
|
outside the library (e.g., in another library or in a top-level
|
|
program) evaluates a reference to one of the library's exported
|
|
variables.
|
|
When the library is invoked, its body expressions (the right-hand-sides
|
|
of the library's variable definitions and its initialization
|
|
expressions) are evaluated.
|
|
Once invoked, the library is not invoked again within the same process,
|
|
unless it is first explicitly redefined or reloaded.
|
|
|
|
\scheme{invoke-library} explicitly invokes the library specified
|
|
by \var{libref} if it has not already been invoked or has since
|
|
been redefined or reloaded.
|
|
If the library has not yet been loaded, \scheme{invoke-library}
|
|
first loads the library via the process described in
|
|
Section~\ref{SECTUSELIBRARIES}.
|
|
|
|
\scheme{invoke-library} is typically only useful for libraries whose
|
|
body expressions have side effects.
|
|
It is useful to control when the side effects occur and to force
|
|
invocation of a library that has no exported variables.
|
|
Invoking a library does not force the compile-time code (macro
|
|
transformer expressions and meta definitions) to be loaded or
|
|
evaluated, nor does it cause the library's bindings to become
|
|
visible.
|
|
|
|
It is good practice to avoid externally visible side effects in
|
|
library bodies so the library can be used equally well at compile
|
|
time and run time.
|
|
When feasible, consider moving the side effects of a library body
|
|
to an initialization routine and adding a top-level program that
|
|
imports the library and calls the initialization routine.
|
|
With this structure, calls to \scheme{invoke-library} on the
|
|
library can be replaced by calls to
|
|
\index{\scheme{load-program}}\scheme{load-program} on the
|
|
top-level program.
|
|
|
|
\section{Library Parameters\label{SECTLIBRARYPARAMETERS}}
|
|
|
|
\index{\scheme{import}}%
|
|
The parameters described below control where \scheme{import} looks
|
|
when attempting to load a library, whether it compiles the libraries
|
|
it loads, and whether it displays tracking messages as it performs its
|
|
search.
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{library-directories}{\categorythreadparameter}{library-directories}
|
|
\formdef{library-extensions}{\categorythreadparameter}{library-extensions}
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
The parameter \scheme{library-directories} determines where the files
|
|
containing library source and object code are located in the file system,
|
|
and the parameter \scheme{library-extensions} determines the filename
|
|
extensions for the files holding the code, as described in
|
|
section~\ref{SECTUSELIBRARIES}.
|
|
The values of both parameters are lists of pairs of strings.
|
|
The first string in each \scheme{library-directories} pair identifies a
|
|
source-file root directory, and the second identifies the corresponding
|
|
object-file root directory.
|
|
Similarly, the first string in each \scheme{library-extensions} pair
|
|
identifies a source-file extension, and the second identifies the
|
|
corresponding object-file extension.
|
|
The full path of a library source or object file consists of the source or
|
|
object root followed by the components of the library name prefixed by
|
|
slashes, with the library extension added on the end.
|
|
For example, for root \scheme{/usr/lib/scheme}, library name
|
|
\scheme{(app lib1)}, and extension \scheme{.sls}, the full path is
|
|
\scheme{/usr/lib/scheme/app/lib1.sls}.
|
|
If the library name portion forms an absolute pathname, e.g.,
|
|
\scheme{~/.myappinit}, the \scheme{library-directories} parameter is
|
|
ignored and no prefix is added.
|
|
|
|
The initial values of these parameters are shown below.
|
|
|
|
\schemedisplay
|
|
(library-directories) ;=> (("." . "."))
|
|
|
|
(library-extensions) ;=> ((".chezscheme.sls" . ".chezscheme.so")
|
|
;== (".ss" . ".so")
|
|
;== (".sls" . ".so")
|
|
;== (".scm" . ".so")
|
|
;== (".sch" . ".so"))
|
|
\endschemedisplay
|
|
|
|
As a convenience, when either of these parameters is set, any element of
|
|
the list can be specified as a single source string, in which case the
|
|
object string is determined automatically.
|
|
For \scheme{library-directories}, the object string is the same as
|
|
the source string, effectively naming the
|
|
same directory as a source- and object-code root.
|
|
For \scheme{library-extensions}, the object string is the result of
|
|
removing the last (or only) extension from the string and appending
|
|
\scheme{".so"}.
|
|
The \scheme{library-directories} and \scheme{library-extensions}
|
|
parameters also accept as input strings in the format described
|
|
in Section~\ref{SECTUSESCRIPTING}
|
|
for the
|
|
\index{\scheme{--libdirs} command-line option}\scheme{--libdirs} and
|
|
\index{\scheme{--libexts} command-line option}\scheme{--libexts} command-line
|
|
options.
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{compile-imported-libraries}{\categorythreadparameter}{compile-imported-libraries}
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
When the value of this parameter is \scheme{#t}, \scheme{import}
|
|
automatically calls the value of the \scheme{compile-library-handler} parameter (which defaults
|
|
to a procedure that simply calls \scheme{compile-library}) on any imported library if
|
|
the object file is missing, older than the corresponding source file,
|
|
older than any source files included (via \index{\scheme{include}}\scheme{include}) when the
|
|
object file was created, or itself requires a library that has or must
|
|
be recompiled, as described in Section~\ref{SECTUSELIBRARIES}.
|
|
The default initial value of this parameter is \scheme{#f}.
|
|
It can be set to \scheme{#t} via the command-line option
|
|
\index{\scheme{--compile-imported-libraries} command-line option}\scheme{--compile-imported-libraries}.
|
|
|
|
When \scheme{import} compiles a library via this mechanism, it does not
|
|
also load the compiled library, because this would cause portions of
|
|
library to be reevaluated.
|
|
Because of this, run-time expressions in the file outside of a
|
|
\scheme{library} form will not be evaluated.
|
|
If such expressions are present and should be evaluated, the library
|
|
should be loaded explicitly.
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{import-notify}{\categorythreadparameter}{import-notify}
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
When the new parameter \scheme{import-notify} is set to a true value,
|
|
\scheme{import} displays messages to the console-output port as it
|
|
searches for the file containing each library it needs to load.
|
|
The default value of this parameter is \scheme{#f}.
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{library-search-handler}{\categorythreadparameter}{library-search-handler}
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
The value of parameter must be a procedure that follows the protocol described
|
|
below for \scheme{default-library-search-handler}, which is the default value
|
|
of this parameter.
|
|
|
|
The value of this parameter is invoked to locate the source or object code for
|
|
a library during \scheme{import}, \scheme{compile-whole-program}, or
|
|
\scheme{compile-whole-library}.
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{default-library-search-handler}{\categoryprocedure}{(default-library-search-handler \var{who} \var{library} \var{directories} \var{extensions})}
|
|
\returns see below
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
This procedure is the default value of the \scheme{library-search-handler},
|
|
which is
|
|
called to locate the source or object code for a library
|
|
during \scheme{import},
|
|
\scheme{compile-whole-program}, or \scheme{compile-whole-library}.
|
|
\var{who} is a symbol that provides context in \scheme{import-notify} messages.
|
|
\var{library} is the name of the desired library.
|
|
\var{directories} is a list of source and object directory pairs in
|
|
the form returned by \scheme{library-directories}.
|
|
\var{extensions} is a list of source and object extension pairs in the form
|
|
returned by \scheme{library-extensions}.
|
|
|
|
This procedure searches the specified directories until it finds a library source or
|
|
object file with one of the specified extensions.
|
|
If it finds the source file first, it constructs the corresponding
|
|
object file path and checks whether the file exists.
|
|
If it finds the object file first, the procedure looks for a corresponding
|
|
source file with one of the given source extensions in a source directory paired
|
|
with that object directory.
|
|
The procedure returns three values:
|
|
the file-system path of the library source file or \scheme{#f} if not found,
|
|
the file-system path of the corresponding object file, which may be \scheme{#f},
|
|
and a boolean that is true if the object file exists.
|
|
|
|
\section{Library Inspection\label{SECTLIBRARYINSPECTION}}
|
|
|
|
%----------------------------------------------------------------------------
|
|
\noskipentryheader
|
|
\formdef{library-list}{\categoryprocedure}{(library-list)}
|
|
\returns a list of the libraries currently defined
|
|
\listlibraries
|
|
\endnoskipentryheader
|
|
|
|
The set of libraries initially defined includes those listed in
|
|
Section~\ref{SECTBUILTINLIBRARIES} above.
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{library-version}{\categoryprocedure}{(library-version \var{libref})}
|
|
\returns the version of the specified library
|
|
\formdef{library-exports}{\categoryprocedure}{(library-exports \var{libref})}
|
|
\returns a list of the exports of the specified library
|
|
\formdef{library-requirements}{\categoryprocedure}{(library-requirements \var{libref})}
|
|
\returns a list of libraries required by the specified library
|
|
\formdef{library-requirements}{\categoryprocedure}{(library-requirements \var{libref} \var{options})}
|
|
\returns a list of libraries required by the specified library, filtered by \var{options}
|
|
\formdef{library-object-filename}{\categoryprocedure}{(library-object-filename \var{libref})}
|
|
\returns the name of the object file holding the specified library, if any
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
Information can be obtained only for built-in libraries or libraries
|
|
previously loaded into the system.
|
|
\var{libref} must be an s-expression in the form of a library reference.
|
|
The syntax for library references is given in
|
|
Chapter~\ref{TSPL:CHPTLIBRARIES} of {\TSPLFOUR} and in the Revised$^6$
|
|
Report.
|
|
|
|
The \scheme{library-version} return value is a list of numbers
|
|
(possibly empty) representing the library's version.
|
|
|
|
The list of exports returned by \scheme{library-exports} is a list of
|
|
symbols, each identifying one of the library's exports.
|
|
The order in which the elements appear is unspecified.
|
|
|
|
When the optional \var{options} argument is supplied, it must be
|
|
an enumeration set over the symbols constituting
|
|
valid library-requirements options, as described in the
|
|
\scheme{library-requirements-options} entry below.
|
|
It defaults to a set containing all of the options.
|
|
Each element of the list of libraries returned by
|
|
\scheme{library-requirements} is an s-expression form of a library
|
|
reference.
|
|
The library reference includes the actual version of the library that is
|
|
present in the system (if nonempty), even if a version was not specified
|
|
when it was imported.
|
|
The order in which the libraries appear in the list returned by
|
|
\scheme{library-requirements} is unspecified.
|
|
|
|
\scheme{library-object-filename} returns a string naming the object
|
|
file if the specified library was loaded from or compiled to an object
|
|
file.
|
|
Otherwise, it returns \scheme{#f}.
|
|
|
|
|
|
\schemedisplay
|
|
(with-output-to-file "A.ss"
|
|
(lambda ()
|
|
(pretty-print
|
|
'(library (A (1 2)) (export x z)
|
|
(import (rnrs))
|
|
(define x 'ex)
|
|
(define y 23)
|
|
(define-syntax z
|
|
(syntax-rules ()
|
|
[(_ e) (+ y e)])))))
|
|
'replace)
|
|
(with-output-to-file "B.ss"
|
|
(lambda ()
|
|
(pretty-print
|
|
'(library (B) (export x w)
|
|
(import (rnrs) (A))
|
|
(define w (cons (z 12) x)))))
|
|
'replace)
|
|
(compile-imported-libraries #t)
|
|
(import (B))
|
|
(library-exports '(A)) ;=> (x z) ; or (z x)
|
|
(library-exports '(A (1 2))) ;=> (x z) ; or (z x)
|
|
(library-exports '(B)) ;=> (x w) ; or (w x)
|
|
(library-version '(A)) ;=> (1 2)
|
|
(library-version '(B)) ;=> ()
|
|
(library-requirements '(A)) ;=> ((rnrs (6)))
|
|
(library-requirements '(B)) ;=> ((rnrs (6)) (A (1 2)))
|
|
(library-object-filename '(A)) ;=> "A.so"
|
|
(library-object-filename '(B)) ;=> "B.so"
|
|
\endschemedisplay
|
|
|
|
%----------------------------------------------------------------------------
|
|
\entryheader
|
|
\formdef{library-requirements-options}{\categorysyntax}{(library-requirements-options \var{symbol} \dots)}
|
|
\returns a library-requirements-options enumeration set
|
|
\listlibraries
|
|
\endentryheader
|
|
|
|
\noindent
|
|
Library-requirements-options enumeration sets are passed to
|
|
\scheme{library-requirements} to determine the library requirements
|
|
to be listed. The available options are described below.
|
|
|
|
\begin{description}
|
|
\item[\scheme{import}:]
|
|
Include the libraries that must be imported when the specified library
|
|
is imported.
|
|
|
|
\item[\scheme{visit@visit}:]
|
|
Includes the libraries that must be visited when the specified library
|
|
is visited.
|
|
|
|
\item[\scheme{invoke@visit}:]
|
|
Include the libraries that must be invoked when the specified library
|
|
is visited.
|
|
|
|
\item[\scheme{invoke}:]
|
|
Includes the libraries that must be invoked when the specified library
|
|
is invoked.
|
|
\end{description}
|
|
|