712 lines
33 KiB
HTML
712 lines
33 KiB
HTML
|
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<!--
|
||
|
|
||
|
Generated from r6rs.tex by tex2page, v 20100828
|
||
|
(running on MzScheme 4.2.4, :unix),
|
||
|
(c) Dorai Sitaram,
|
||
|
http://evalwhen.com/tex2page/index.html
|
||
|
|
||
|
-->
|
||
|
<head>
|
||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
|
<title>
|
||
|
Revised^6 Report on the Algorithmic Language Scheme
|
||
|
</title>
|
||
|
<link rel="stylesheet" type="text/css" href="r6rs-Z-S.css" title=default>
|
||
|
<meta name=robots content="index,follow">
|
||
|
</head>
|
||
|
<body>
|
||
|
<div id=slidecontent>
|
||
|
<div align=right class=navigation>[Go to <span><a href="r6rs.html">first</a>, <a href="r6rs-Z-H-9.html">previous</a></span><span>, <a href="r6rs-Z-H-11.html">next</a></span> page<span>; </span><span><a href="r6rs-Z-H-2.html#node_toc_start">contents</a></span><span><span>; </span><a href="r6rs-Z-H-21.html#node_index_start">index</a></span>]</div>
|
||
|
<p></p>
|
||
|
<a name="node_chap_7"></a>
|
||
|
<h1 class=chapter>
|
||
|
<div class=chapterheading><a href="r6rs-Z-H-2.html#node_toc_node_chap_7">Chapter 7</a></div><br>
|
||
|
<a href="r6rs-Z-H-2.html#node_toc_node_chap_7">Libraries</a></h1>
|
||
|
<p>
|
||
|
<a name="node_idx_264"></a>Libraries are parts of a program that can be distributed
|
||
|
independently.
|
||
|
The library system supports macro definitions within libraries,
|
||
|
macro exports, and distinguishes the phases in which definitions
|
||
|
and imports are needed. This chapter defines the notation for
|
||
|
libraries and a semantics for library expansion and execution.</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<a name="node_sec_7.1"></a>
|
||
|
<h2 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_7.1">7.1 Library form</a></h2>
|
||
|
<p></p>
|
||
|
<p>
|
||
|
A library definition must have the following form:<a name="node_idx_266"></a><a name="node_idx_268"></a><a name="node_idx_270"></a></p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt>(library <library name>
|
||
|
<p class=nopadding> (export <export spec> <tt>...</tt>)</p>
|
||
|
|
||
|
<p class=nopadding> (import <import spec> <tt>...</tt>)</p>
|
||
|
|
||
|
<p class=nopadding> <library body>)</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
A library declaration contains the following elements:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li><p>The <library name> specifies the name of the library
|
||
|
(possibly with version).
|
||
|
</p>
|
||
|
<li><p>The <tt>export</tt> subform specifies a list of exports, which name
|
||
|
a subset of the bindings defined within or imported into the
|
||
|
library.
|
||
|
</p>
|
||
|
<li><p>The <tt>import</tt> subform specifies the imported bindings as a
|
||
|
list of import dependencies, where each dependency specifies:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li><p>the imported library's name, and, optionally, constraints on its
|
||
|
version,
|
||
|
</p>
|
||
|
<li><p>the relevant levels, e.g., expand or run time (see
|
||
|
section <a href="r6rs-Z-H-10.html#node_sec_7.2">7.2</a>, and
|
||
|
</p>
|
||
|
<li><p>the subset of the library's exports to make available within the
|
||
|
importing library, and the local names to use within the importing
|
||
|
library for each of the library's exports.
|
||
|
</p>
|
||
|
</ul><p>
|
||
|
</p>
|
||
|
<li><p>The <library body> is the library body, consisting of a
|
||
|
sequence of definitions followed by a sequence of expressions. The
|
||
|
definitions may be both for local (unexported) and exported
|
||
|
bindings, and the expressions are initialization expressions to be evaluated
|
||
|
for their effects.
|
||
|
</p>
|
||
|
</ul><p></p>
|
||
|
<p>
|
||
|
An identifier can be imported with the same local name from two or
|
||
|
more libraries or for two levels from the same library only if the
|
||
|
binding exported by each library is the same (i.e., the binding is
|
||
|
defined in one library, and it arrives through the imports only by
|
||
|
exporting and re-exporting). Otherwise, no identifier can be imported
|
||
|
multiple times, defined multiple times, or both defined and imported.
|
||
|
No identifiers are visible within a library except for those
|
||
|
explicitly imported into the library or defined within the library.</p>
|
||
|
<p>
|
||
|
A <library name> uniquely identifies a library within an
|
||
|
implementation, and is globally visible in the <tt>import</tt> clauses
|
||
|
(see below) of all other libraries within an implementation.
|
||
|
A <library name> has the following form:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt>(<identifier<sub>1</sub>> <identifier<sub>2</sub>> <tt>...</tt> <version>)<p></tt></p>
|
||
|
<p>
|
||
|
where <version> is empty or has the following form:
|
||
|
</p>
|
||
|
|
||
|
<tt>(<sub-version> <tt>...</tt>)<p></tt></p>
|
||
|
<p>
|
||
|
Each <sub-version> must represent an exact nonnegative integer object.
|
||
|
An empty <version> is equivalent to <tt>()</tt>.</p>
|
||
|
<p>
|
||
|
An <export spec> names a set of imported and locally defined bindings to
|
||
|
be exported, possibly with different
|
||
|
external names. An <export spec> must have one of the
|
||
|
following forms:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt><identifier>
|
||
|
<p class=nopadding>(rename (<identifier<sub>1</sub>> <identifier<sub>2</sub>>) <tt>...</tt>)</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
In an <export spec>, an <identifier> names a single binding defined
|
||
|
within or imported into the library, where the external name for the export is
|
||
|
the same as the name of the binding within the library.
|
||
|
A <tt>rename</tt> spec exports the binding named by
|
||
|
<identifier<sub>1</sub>> in each <tt>(<identifier<sub>1</sub>>
|
||
|
<identifier<sub>2</sub>>)</tt> pairing, using <identifier<sub>2</sub>> as the
|
||
|
external name.</p>
|
||
|
<p>
|
||
|
Each <import spec> specifies a set of bindings to be imported into
|
||
|
the library, the levels at which they are to be available, and the local
|
||
|
names by which they are to be known. An <import spec> must
|
||
|
be one of the following:
|
||
|
</p>
|
||
|
|
||
|
<tt><import set>
|
||
|
<p class=nopadding>(for <import set> <import level> <tt>...</tt>)</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
An <import level> is one of the following:
|
||
|
</p>
|
||
|
|
||
|
<tt>run
|
||
|
<p class=nopadding>expand</p>
|
||
|
|
||
|
<p class=nopadding>(meta <level>)</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
where <level> represents an exact integer object.</p>
|
||
|
<p>
|
||
|
As an <import level>, <tt>run</tt> is an abbreviation for <tt>(meta 0)</tt>, and <tt>expand</tt> is an abbreviation for <tt>(meta 1)</tt>.
|
||
|
Levels and phases are discussed in section <a href="r6rs-Z-H-10.html#node_sec_7.2">7.2</a>.</p>
|
||
|
<p>
|
||
|
An <import set> names a set of bindings from another library and
|
||
|
possibly specifies local names for the imported bindings. It must be
|
||
|
one of the following:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt><library reference>
|
||
|
<p class=nopadding>(library <library reference>)</p>
|
||
|
|
||
|
<p class=nopadding>(only <import set> <identifier> <tt>...</tt>)</p>
|
||
|
|
||
|
<p class=nopadding>(except <import set> <identifier> <tt>...</tt>)</p>
|
||
|
|
||
|
<p class=nopadding>(prefix <import set> <identifier>)</p>
|
||
|
|
||
|
<p class=nopadding>(rename <import set> (<identifier<sub>1</sub>> <identifier<sub>2</sub>>) <tt>...</tt>)</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
A <library reference> identifies a library by its
|
||
|
name and optionally by its version. It has one of the following forms:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt>(<identifier<sub>1</sub>> <identifier<sub>2</sub>> <tt>...</tt>)
|
||
|
<p class=nopadding>(<identifier<sub>1</sub>> <identifier<sub>2</sub>> <tt>...</tt> <version reference>)</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
A <library reference> whose first <identifier> is
|
||
|
<tt>for</tt>, <tt>library</tt>, <tt>only</tt>, <tt>except</tt>, <tt>prefix</tt>, or <tt>rename</tt> is
|
||
|
permitted only within a <tt>library</tt> <import set>.
|
||
|
The <import set> <tt>(library <library reference>)</tt> is
|
||
|
otherwise equivalent to <library reference>.</p>
|
||
|
<p>
|
||
|
A <library reference> with no <version reference>
|
||
|
(first form above) is equivalent to a <library reference> with a
|
||
|
<version reference> of <tt>()</tt>.</p>
|
||
|
<p>
|
||
|
A <version reference> specifies a set of <version>s that
|
||
|
it matches. The <library reference> identifies all libraries of
|
||
|
the same name and whose version is matched by the
|
||
|
<version reference>. A <version reference> has
|
||
|
the following form:
|
||
|
</p>
|
||
|
|
||
|
<tt>(<sub-version reference<sub>1</sub>> <tt>...</tt> <sub-version reference<sub><em>n</em></sub>>)
|
||
|
<p class=nopadding>(and <version reference> <tt>...</tt>)</p>
|
||
|
|
||
|
<p class=nopadding>(or <version reference> <tt>...</tt>)</p>
|
||
|
|
||
|
<p class=nopadding>(not <version reference>)</p>
|
||
|
<p></tt>
|
||
|
A <version reference> of the first form matches a <version>
|
||
|
with at least <em>n</em> elements, whose <sub-version reference>s match
|
||
|
the corresponding <sub-version>s. An <tt>and</tt> <version
|
||
|
reference> matches a version if all <version references>
|
||
|
following the <tt>and</tt> match it. Correspondingly, an <tt>or</tt> <version reference> matches a version if one of
|
||
|
<version references> following the <tt>or</tt> matches it,
|
||
|
and a <tt>not</tt> <version reference> matches a version if the
|
||
|
<version reference> following it does not match it.</p>
|
||
|
<p>
|
||
|
A <sub-version reference> has one of the following forms:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt><sub-version>
|
||
|
<p class=nopadding>(>= <sub-version>)</p>
|
||
|
|
||
|
<p class=nopadding>(<= <sub-version>)</p>
|
||
|
|
||
|
<p class=nopadding>(and <sub-version reference> <tt>...</tt>)</p>
|
||
|
|
||
|
<p class=nopadding>(or <sub-version reference> <tt>...</tt>)</p>
|
||
|
|
||
|
<p class=nopadding>(not <sub-version reference>)</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
A <sub-version reference> of the first form matches a
|
||
|
<sub-version> if it is equal to it. A <tt>>=</tt>
|
||
|
<sub-version reference> of the first form matches a sub-version
|
||
|
if it is greater or equal to the <sub-version> following it;
|
||
|
analogously for <tt><=</tt>. An <tt>and</tt> <sub-version reference>
|
||
|
matches a sub-version if all of the subsequent <sub-version
|
||
|
reference>s match it. Correspondingly, an <tt>or</tt>
|
||
|
<sub-version reference> matches a sub-version if one of the
|
||
|
subsequent <sub-version reference>s matches it, and a <tt>not</tt>
|
||
|
<sub-version reference> matches a sub-version if the subsequent
|
||
|
<sub-version reference> does not match it.</p>
|
||
|
<p>
|
||
|
Examples:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<div align=left><img src="r6rs-Z-G-1.gif" border="0" alt="[r6rs-Z-G-1.gif]"></div><p>
|
||
|
</p>
|
||
|
<p>
|
||
|
When more than one library is identified by a library reference, the
|
||
|
choice of libraries is determined in some implementation-dependent manner.</p>
|
||
|
<p>
|
||
|
To avoid problems such as incompatible types and replicated state,
|
||
|
implementations should prohibit the two libraries whose library names
|
||
|
consist of the same sequence of identifiers but whose versions do not
|
||
|
match to co-exist in the same program.</p>
|
||
|
<p>
|
||
|
By default, all of an imported library's exported bindings are made
|
||
|
visible within an importing library using the names given to the bindings
|
||
|
by the imported library.
|
||
|
The precise set of bindings to be imported and the names of those
|
||
|
bindings can be adjusted with the <tt>only</tt>, <tt>except</tt>,
|
||
|
<tt>prefix</tt>, and <tt>rename</tt> forms as described below.</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li><p>An <tt>only</tt> form produces a subset of the bindings from another
|
||
|
<import set>, including only the listed
|
||
|
<identifier>s.
|
||
|
The included <identifier>s must be in
|
||
|
the original <import set>.
|
||
|
</p>
|
||
|
<li><p>An <tt>except</tt> form produces a subset of the bindings from another
|
||
|
<import set>, including all but the listed
|
||
|
<identifier>s.
|
||
|
All of the excluded <identifier>s must be in
|
||
|
the original <import set>.
|
||
|
</p>
|
||
|
<li><p>A <tt>prefix</tt> form adds the <identifier> prefix to each
|
||
|
name from another <import set>.
|
||
|
</p>
|
||
|
<li><p>A <tt>rename</tt> form, <tt>(rename (<identifier<sub>1</sub>> <identifier<sub>2</sub>>) <tt>...</tt>)</tt>,
|
||
|
removes the bindings for <tt><identifier<sub>1</sub>> <tt>...</tt></tt> to form an
|
||
|
intermediate <import set>, then adds the bindings back for the
|
||
|
corresponding <tt><identifier<sub>2</sub>> <tt>...</tt></tt> to form the final
|
||
|
<import set>.
|
||
|
Each <identifier<sub>1</sub>> must be in the original <import set>,
|
||
|
each <identifier<sub>2</sub>> must not be in the intermediate <import set>,
|
||
|
and the <identifier<sub>2</sub>>s must be distinct.
|
||
|
</p>
|
||
|
</ul><p>
|
||
|
It is a syntax violation if a constraint given above is not met.</p>
|
||
|
<p>
|
||
|
|
||
|
The <library body> of a <tt>library</tt> form consists of forms
|
||
|
that are classified as
|
||
|
<i>definitions</i><a name="node_idx_272"></a>or
|
||
|
<i>expressions</i><a name="node_idx_274"></a>. Which forms belong to
|
||
|
which class depends on the imported libraries and the result of
|
||
|
expansion—see chapter <a href="r6rs-Z-H-13.html#node_chap_10">10</a>. Generally, forms that
|
||
|
are not
|
||
|
definitions (see section <a href="r6rs-Z-H-14.html#node_sec_11.2">11.2</a> for definitions available
|
||
|
through the base library) are expressions.</p>
|
||
|
<p>
|
||
|
A <library body> is like a <body> (see section <a href="r6rs-Z-H-14.html#node_sec_11.3">11.3</a>) except that
|
||
|
a <library body>s need not include any expressions. It must
|
||
|
have the following form:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt><definition> <tt>...</tt> <expression> <tt>...</tt><p></tt></p>
|
||
|
<p>
|
||
|
When <tt>begin</tt>, <tt>let-syntax</tt>, or <tt>letrec-syntax</tt> forms
|
||
|
occur in a top-level body prior to the first
|
||
|
expression, they are spliced into the body; see section <a href="r6rs-Z-H-14.html#node_sec_11.4.7">11.4.7</a>.
|
||
|
Some or all of the body, including portions wrapped in <tt>begin</tt>,
|
||
|
<tt>let-syntax</tt>, or <tt>letrec-syntax</tt>
|
||
|
forms, may be specified by a syntactic abstraction
|
||
|
(see section <a href="r6rs-Z-H-12.html#node_sec_9.2">9.2</a>).</p>
|
||
|
<p>
|
||
|
The transformer expressions and bindings are evaluated and created
|
||
|
from left to right, as described in chapter <a href="r6rs-Z-H-13.html#node_chap_10">10</a>.
|
||
|
The expressions of variable definitions are evaluated
|
||
|
from left to right, as if in an implicit <tt>letrec*</tt>,
|
||
|
and the body expressions are also evaluated from left to right
|
||
|
after the expressions of the variable definitions.
|
||
|
A fresh location is created for each exported variable and initialized
|
||
|
to the value of its local counterpart.
|
||
|
The effect of returning twice to the continuation of the last body
|
||
|
expression is unspecified.</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<blockquote><em>Note:<span style="margin-left: .5em">‌</span></em>
|
||
|
The names <tt>library</tt>, <tt>export</tt>, <tt>import</tt>,
|
||
|
<tt>for</tt>, <tt>run</tt>, <tt>expand</tt>, <tt>meta</tt>,
|
||
|
<tt>import</tt>, <tt>export</tt>, <tt>only</tt>, <tt>except</tt>, <tt>prefix</tt>, <tt>rename</tt>, <tt>and</tt>, <tt>or</tt>, <tt>not</tt>, <tt>>=</tt>, and <tt><=</tt>
|
||
|
appearing in the library syntax are part of the
|
||
|
syntax and are not reserved, i.e., the same names can be used for other
|
||
|
purposes within the library or even exported from or imported
|
||
|
into a library with different meanings, without affecting their
|
||
|
use in the <tt>library</tt> form.
|
||
|
</blockquote><p>
|
||
|
Bindings defined with a library are not visible in code
|
||
|
outside of the library, unless the bindings are explicitly exported from the
|
||
|
library.
|
||
|
An exported macro may, however, <em>implicitly export</em> an otherwise
|
||
|
unexported identifier defined within or imported into the library.
|
||
|
That is, it may insert a reference to that identifier into the output code
|
||
|
it produces.</p>
|
||
|
<p>
|
||
|
|
||
|
All explicitly exported variables are immutable in both the
|
||
|
exporting and importing libraries.
|
||
|
It is thus a syntax violation if an
|
||
|
explicitly exported variable appears on the left-hand side of a <tt>set!</tt>
|
||
|
expression, either in the exporting or importing libraries.</p>
|
||
|
<p>
|
||
|
All implicitly exported variables are also immutable in both the
|
||
|
exporting and importing libraries.
|
||
|
It is thus a syntax violation if a
|
||
|
variable appears on the left-hand side of a <tt>set!</tt>
|
||
|
expression in any code produced by an exported macro outside of the
|
||
|
library in which the variable is defined.
|
||
|
It is also a syntax violation if a
|
||
|
reference to an assigned variable appears in any code produced by
|
||
|
an exported macro outside of the library in which the variable is defined,
|
||
|
where an assigned variable is one that appears on the left-hand
|
||
|
side of a <tt>set!</tt> expression in the exporting library.</p>
|
||
|
<p>
|
||
|
All other variables defined within a library are mutable.</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<a name="node_sec_7.2"></a>
|
||
|
<h2 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_7.2">7.2 Import and export levels</a></h2>
|
||
|
<p></p>
|
||
|
<p>
|
||
|
Expanding a library may require run-time information from another
|
||
|
library. For example, if a macro transformer calls a
|
||
|
procedure from library <em>A</em>, then the library <em>A</em> must be
|
||
|
instantiated before expanding any use of the macro in library <em>B</em>. Library <em>A</em> may
|
||
|
not be
|
||
|
needed when library <em>B</em> is eventually run as part of a program, or it
|
||
|
may be needed for run time of library <em>B</em>, too. The library
|
||
|
mechanism distinguishes these times by phases, which are explained in
|
||
|
this section.</p>
|
||
|
<p>
|
||
|
Every library can be characterized by expand-time information (minimally,
|
||
|
its imported libraries, a list of the exported keywords, a list of the
|
||
|
exported variables, and code to evaluate the transformer expressions) and
|
||
|
run-time information (minimally, code to evaluate the variable definition
|
||
|
right-hand-side expressions, and code to evaluate the body expressions).
|
||
|
The expand-time information must be available to expand references to
|
||
|
any exported binding, and the run-time information must be available to
|
||
|
evaluate references to any exported variable binding.</p>
|
||
|
<p>
|
||
|
<a name="node_idx_276"></a>A <em>phase</em> is a time at which the expressions within a library are
|
||
|
evaluated.
|
||
|
Within a library body, top-level expressions and
|
||
|
the right-hand sides of <tt>define</tt> forms are evaluated at run time,
|
||
|
i.e., phase 0, and the right-hand
|
||
|
sides of <tt>define-syntax</tt> forms are evaluated at expand time, i.e.,
|
||
|
phase 1.
|
||
|
When <tt>define-syntax</tt>,
|
||
|
<tt>let-syntax</tt>, or <tt>letrec-syntax</tt>
|
||
|
forms appear within code evaluated at phase <em>n</em>, the right-hand sides
|
||
|
are evaluated at phase <em>n</em> + 1.</p>
|
||
|
<p>
|
||
|
These phases are relative to the phase in which the library itself is
|
||
|
used.
|
||
|
An <a name="node_idx_278"></a><em>instance</em> of a library corresponds to an evaluation of its
|
||
|
variable definitions and expressions in a particular phase relative to another
|
||
|
library—a process called <a name="node_idx_280"></a><em>instantiation</em>.
|
||
|
For example, if a top-level expression in a library <em>B</em> refers to
|
||
|
a variable export from another library <em>A</em>, then it refers to the export from an
|
||
|
instance of <em>A</em> at phase 0 (relative to the phase of <em>B</em>).
|
||
|
But if a phase 1 expression within <em>B</em> refers to the same binding from
|
||
|
<em>A</em>, then it refers to the export from an instance of <em>A</em> at phase 1
|
||
|
(relative to the phase of <em>B</em>).</p>
|
||
|
<p>
|
||
|
A <a name="node_idx_282"></a><em>visit</em> of a library corresponds to the evaluation of its syntax
|
||
|
definitions in a particular phase relative to another
|
||
|
library—a process called <a name="node_idx_284"></a><em>visiting</em>.
|
||
|
For example, if a top-level expression in a library <em>B</em> refers to
|
||
|
a macro export from another library <em>A</em>, then it refers to the export from a
|
||
|
visit of <em>A</em> at phase 0 (relative to the phase of <em>B</em>), which corresponds
|
||
|
to the evaluation of the macro's transformer expression at phase 1.</p>
|
||
|
<p>
|
||
|
<a name="node_idx_286"></a><a name="node_idx_288"></a>A <em>level</em> is a lexical property of an identifier that determines
|
||
|
in which phases it can be referenced. The level for each identifier
|
||
|
bound by a definition within a library is 0; that is, the identifier
|
||
|
can be referenced only at phase 0 within the library.
|
||
|
The level for each imported binding is determined by the enclosing <tt>for</tt> form of the <tt>import</tt> in the importing library, in
|
||
|
addition to the levels of the identifier in the exporting
|
||
|
library. Import and export levels are combined by pairwise addition of
|
||
|
all level combinations. For example, references to an imported
|
||
|
identifier exported for levels <em>p</em><sub><em>a</em></sub> and <em>p</em><sub><em>b</em></sub> and imported for levels
|
||
|
<em>q</em><sub><em>a</em></sub>, <em>q</em><sub><em>b</em></sub>, and <em>q</em><sub><em>c</em></sub> are valid at levels <em>p</em><sub><em>a</em></sub> + <em>q</em><sub><em>a</em></sub>, <em>p</em><sub><em>a</em></sub> + <em>q</em><sub><em>b</em></sub>,
|
||
|
<em>p</em><sub><em>a</em></sub> + <em>q</em><sub><em>c</em></sub>, <em>p</em><sub><em>b</em></sub> + <em>q</em><sub><em>a</em></sub>, <em>p</em><sub><em>b</em></sub> + <em>q</em><sub><em>b</em></sub>, and <em>p</em><sub><em>b</em></sub> + <em>q</em><sub><em>c</em></sub>. An <import set>
|
||
|
without an enclosing <tt>for</tt> is equivalent to <tt>(for
|
||
|
<import set> run)</tt>, which is the same as <tt>(for
|
||
|
<import set> (meta 0))</tt>.</p>
|
||
|
<p>
|
||
|
The export level of an exported binding is 0 for all bindings
|
||
|
that are defined within the exporting library. The export levels of a
|
||
|
reexported binding, i.e., an export imported from another library, are the
|
||
|
same as the effective import levels of that binding within the reexporting
|
||
|
library.</p>
|
||
|
<p>
|
||
|
For the libraries defined in the library report, the export level is
|
||
|
0 for nearly all bindings. The exceptions are <tt>syntax-rules</tt>,
|
||
|
<tt>identifier-syntax</tt>, <tt>...</tt>, and <tt>_</tt> from the
|
||
|
<tt>(rnrs base (6))</tt> library, which are exported with level 1, <tt>set!</tt> from the <tt>(rnrs base (6))</tt> library, which is exported with
|
||
|
levels 0 and 1, and all bindings from the composite
|
||
|
<tt>(rnrs (6))</tt> library (see library
|
||
|
chapter on “Composite library”), which are
|
||
|
exported with levels 0 and 1.</p>
|
||
|
<p>
|
||
|
Macro expansion within a library can introduce a reference to an
|
||
|
identifier that is not explicitly imported into the library. In that
|
||
|
case, the phase of the reference must match the identifier's level as
|
||
|
shifted by the difference between the phase of the source library
|
||
|
(i.e., the library that supplied the identifier's lexical context) and
|
||
|
the library that encloses the reference. For example, suppose that
|
||
|
expanding a library invokes a macro transformer, and the evaluation of
|
||
|
the macro transformer refers to an identifier that is exported from
|
||
|
another library (so the phase-1 instance of the library is used);
|
||
|
suppose further that the value of the binding is a syntax object
|
||
|
representing an identifier with only a level-<em>n</em> binding; then, the
|
||
|
identifier must be used only at phase <em>n</em> + 1 in the
|
||
|
library being expanded. This combination of levels and phases is why
|
||
|
negative levels on identifiers can be useful, even though libraries
|
||
|
exist only at non-negative phases.</p>
|
||
|
<p>
|
||
|
If any of a library's definitions are referenced at phase 0 in the
|
||
|
expanded form of a program, then an instance of the referenced library
|
||
|
is created for phase 0 before the program's definitions and
|
||
|
expressions are evaluated. This rule applies transitively: if the
|
||
|
expanded form of one library references at phase 0 an identifier
|
||
|
from another library, then before the referencing library is
|
||
|
instantiated at phase <em>n</em>, the referenced library must be instantiated
|
||
|
at phase <em>n</em>. When an identifier is referenced at any phase <em>n</em>
|
||
|
greater than 0, in contrast, then the defining library is
|
||
|
instantiated at phase <em>n</em> at some unspecified time before the
|
||
|
reference is evaluated. Similarly, when a macro keyword is referenced at
|
||
|
phase <em>n</em> during the expansion of a library, then the
|
||
|
defining library is visited at phase <em>n</em> at some unspecified time
|
||
|
before the reference is evaluated.</p>
|
||
|
<p>
|
||
|
An implementation may distinguish instances/visits of a library for
|
||
|
different phases or to use an instance/visit at any phase as an instance/visit at
|
||
|
any other phase. An implementation may further
|
||
|
expand each <tt>library</tt> form with distinct
|
||
|
visits of libraries in any phase and/or instances of
|
||
|
libraries in phases above 0. An implementation may
|
||
|
create instances/visits of more libraries at more phases than required to
|
||
|
satisfy references. When an identifier appears as an expression in a
|
||
|
phase that is inconsistent with the identifier's level, then an
|
||
|
implementation may raise an exception either at expand time or run
|
||
|
time, or it may allow the reference. Thus, a library whose meaning depends on whether the
|
||
|
instances of a library are distinguished or shared across phases or
|
||
|
<tt>library</tt> expansions may be unportable.</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<a name="node_sec_7.3"></a>
|
||
|
<h2 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_7.3">7.3 Examples</a></h2>
|
||
|
<p>Examples for various <import spec>s and <export spec>s:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt>(library (stack)
|
||
|
<p class=nopadding> (export make push! pop! empty!)</p>
|
||
|
|
||
|
<p class=nopadding> (import (rnrs))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding> (define (make) (list '()))</p>
|
||
|
|
||
|
<p class=nopadding> (define (push! s v) (set-car! s (cons v (car s))))</p>
|
||
|
|
||
|
<p class=nopadding> (define (pop! s) (let ([v (caar s)])</p>
|
||
|
|
||
|
<p class=nopadding> (set-car! s (cdar s))</p>
|
||
|
|
||
|
<p class=nopadding> v))</p>
|
||
|
|
||
|
<p class=nopadding> (define (empty! s) (set-car! s '())))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding>(library (balloons)</p>
|
||
|
|
||
|
<p class=nopadding> (export make push pop)</p>
|
||
|
|
||
|
<p class=nopadding> (import (rnrs))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding> (define (make w h) (cons w h))</p>
|
||
|
|
||
|
<p class=nopadding> (define (push b amt)</p>
|
||
|
|
||
|
<p class=nopadding> (cons (- (car b) amt) (+ (cdr b) amt)))</p>
|
||
|
|
||
|
<p class=nopadding> (define (pop b) (display "Boom! ") </p>
|
||
|
|
||
|
<p class=nopadding> (display (* (car b) (cdr b))) </p>
|
||
|
|
||
|
<p class=nopadding> (newline)))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding>(library (party)</p>
|
||
|
|
||
|
<p class=nopadding> ;; Total exports:</p>
|
||
|
|
||
|
<p class=nopadding> ;; make, push, push!, make-party, pop!</p>
|
||
|
|
||
|
<p class=nopadding> (export (rename (balloon:make make)</p>
|
||
|
|
||
|
<p class=nopadding> (balloon:push push))</p>
|
||
|
|
||
|
<p class=nopadding> push!</p>
|
||
|
|
||
|
<p class=nopadding> make-party</p>
|
||
|
|
||
|
<p class=nopadding> (rename (party-pop! pop!)))</p>
|
||
|
|
||
|
<p class=nopadding> (import (rnrs)</p>
|
||
|
|
||
|
<p class=nopadding> (only (stack) make push! pop!) ; not empty!</p>
|
||
|
|
||
|
<p class=nopadding> (prefix (balloons) balloon:))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding> ;; Creates a party as a stack of balloons,</p>
|
||
|
|
||
|
<p class=nopadding> ;; starting with two balloons</p>
|
||
|
|
||
|
<p class=nopadding> (define (make-party)</p>
|
||
|
|
||
|
<p class=nopadding> (let ([s (make)]) ; from stack</p>
|
||
|
|
||
|
<p class=nopadding> (push! s (balloon:make 10 10))</p>
|
||
|
|
||
|
<p class=nopadding> (push! s (balloon:make 12 9))</p>
|
||
|
|
||
|
<p class=nopadding> s))</p>
|
||
|
|
||
|
<p class=nopadding> (define (party-pop! p)</p>
|
||
|
|
||
|
<p class=nopadding> (balloon:pop (pop! p))))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding>(library (main)</p>
|
||
|
|
||
|
<p class=nopadding> (export)</p>
|
||
|
|
||
|
<p class=nopadding> (import (rnrs) (party))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding> (define p (make-party))</p>
|
||
|
|
||
|
<p class=nopadding> (pop! p) ; displays "Boom! 108"</p>
|
||
|
|
||
|
<p class=nopadding> (push! p (push (make 5 5) 1))</p>
|
||
|
|
||
|
<p class=nopadding> (pop! p)) ; displays "Boom! 24"</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
Examples for macros and phases:</p>
|
||
|
<p>
|
||
|
</p>
|
||
|
|
||
|
<tt>(library (my-helpers id-stuff)
|
||
|
<p class=nopadding> (export find-dup)</p>
|
||
|
|
||
|
<p class=nopadding> (import (rnrs))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding> (define (find-dup l)</p>
|
||
|
|
||
|
<p class=nopadding> (and (pair? l)</p>
|
||
|
|
||
|
<p class=nopadding> (let loop ((rest (cdr l)))</p>
|
||
|
|
||
|
<p class=nopadding> (cond</p>
|
||
|
|
||
|
<p class=nopadding> [(null? rest) (find-dup (cdr l))]</p>
|
||
|
|
||
|
<p class=nopadding> [(bound-identifier=? (car l) (car rest)) </p>
|
||
|
|
||
|
<p class=nopadding> (car rest)]</p>
|
||
|
|
||
|
<p class=nopadding> [else (loop (cdr rest))])))))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding>(library (my-helpers values-stuff)</p>
|
||
|
|
||
|
<p class=nopadding> (export mvlet)</p>
|
||
|
|
||
|
<p class=nopadding> (import (rnrs) (for (my-helpers id-stuff) expand))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding> (define-syntax mvlet</p>
|
||
|
|
||
|
<p class=nopadding> (lambda (stx)</p>
|
||
|
|
||
|
<p class=nopadding> (syntax-case stx ()</p>
|
||
|
|
||
|
<p class=nopadding> [(_ [(id ...) expr] body0 body ...)</p>
|
||
|
|
||
|
<p class=nopadding> (not (find-dup (syntax (id ...))))</p>
|
||
|
|
||
|
<p class=nopadding> (syntax</p>
|
||
|
|
||
|
<p class=nopadding> (call-with-values</p>
|
||
|
|
||
|
<p class=nopadding> (lambda () expr) </p>
|
||
|
|
||
|
<p class=nopadding> (lambda (id ...) body0 body ...)))]))))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding>(library (let-div)</p>
|
||
|
|
||
|
<p class=nopadding> (export let-div)</p>
|
||
|
|
||
|
<p class=nopadding> (import (rnrs)</p>
|
||
|
|
||
|
<p class=nopadding> (my-helpers values-stuff)</p>
|
||
|
|
||
|
<p class=nopadding> (rnrs r5rs))</p>
|
||
|
|
||
|
<p class=nopadding></p>
|
||
|
|
||
|
<p class=nopadding> (define (quotient+remainder n d)</p>
|
||
|
|
||
|
<p class=nopadding> (let ([q (quotient n d)])</p>
|
||
|
|
||
|
<p class=nopadding> (values q (- n (* q d)))))</p>
|
||
|
|
||
|
<p class=nopadding> (define-syntax let-div</p>
|
||
|
|
||
|
<p class=nopadding> (syntax-rules ()</p>
|
||
|
|
||
|
<p class=nopadding> [(_ n d (q r) body0 body ...)</p>
|
||
|
|
||
|
<p class=nopadding> (mvlet [(q r) (quotient+remainder n d)]</p>
|
||
|
|
||
|
<p class=nopadding> body0 body ...)])))</p>
|
||
|
<p></tt></p>
|
||
|
<p>
|
||
|
</p>
|
||
|
<p></p>
|
||
|
<div class=smallskip></div>
|
||
|
<p style="margin-top: 0pt; margin-bottom: 0pt">
|
||
|
<div align=right class=navigation>[Go to <span><a href="r6rs.html">first</a>, <a href="r6rs-Z-H-9.html">previous</a></span><span>, <a href="r6rs-Z-H-11.html">next</a></span> page<span>; </span><span><a href="r6rs-Z-H-2.html#node_toc_start">contents</a></span><span><span>; </span><a href="r6rs-Z-H-21.html#node_index_start">index</a></span>]</div>
|
||
|
</p>
|
||
|
<p></p>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|