File: module.texi

package info (click to toggle)
s48-refman 1-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 712 kB
  • sloc: makefile: 37
file content (156 lines) | stat: -rw-r--r-- 7,032 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
@node Using the module system
@section Using the module system

Scheme48 is deeply integrated with an advanced module system.  For
complete detail of its module system, @pxref{Module system}.  Briefly,
however:

@itemize
@item @dfn{Packages} are top-level environments suitable for
evaluating expressions and definitions, either interactively, from
files loaded on-the-fly, or as the bodies of modules.  They can also
access bindings exported by structures by @dfn{opening} the
structures.

@item @dfn{Structures} are libraries, or implementations of
interfaces, exporting sets of bindings that packages can access.
Underlying structures are usually packages, in which the user can, in
some cases, interactively evaluate code during development.
@end itemize

Scheme48's usual development system, the command processor, provides a
number of commands for working with the module system.  For complete
details, @pxref{Module commands}.  Chief among these commands are
@command{,open} and @command{,in}.  @samp{,open @var{struct} @dots{}}
makes all of the bindings from each of @var{struct} @dots{} available
in the interaction environment.  Many of the sections in this manual
describe one or more structures with the name they are given.  For
example, in order to use, or open, the multi-dimensional array library
in the current interaction environment, one would enter

@lisp
,open arrays@end lisp

@noindent
to the command processor.  @samp{,in @var{struct}} sets the
interaction environment to be the package underlying @var{struct}.
For instance, if, during development, the user decides that the
package of the existing structure @code{foo} should open the structure
@code{bar}, he might type

@lisp
,in foo
,open bar@end lisp

Module descriptions, or code in the @embedref{Module configuration
language, module configuration language} should be loaded into the
special environment for that language with the @code{,config} command
(@pxref{Module commands}).  @Eg{}, if @file{packages.scm} contains a
set of module descriptions that the user wishes to load, among which
is the definition of a structure @code{frobozz} which he wishes to
open, he will typically send the following to the command processor
prompt:

@lisp
,config ,load packages.scm
,open frobozz@end lisp

@strong{Note:} These are commands for the interactive command
processor, @emph{not} special directives to store in files to work
with the module system.  The module language is disjoint from Scheme;
for complete detail on it, @pxref{Module system}.

@subsection Configuration mutation

@i{(This section was derived from work copyrighted (C) 1993-2005 by
Richard Kelsey, Jonathan Rees, and Mike Sperber.)}

@cindex code reloading
@cindex reloading code
@texonlyindent
During program development, it is often desirable to make changes to
packages and interfaces.  In static languages, it is usually necessary
to re-compile and re-link a program in order for such changes to be
reflected in a running system.  Even in interactive Common Lisp
systems, a change to a package's exports often requires reloading
clients that have already mentioned names whose bindings change.  In
those systems, once @code{read} resolves a use of a name to a symbol,
that resolution is fixed, so a change in the way that a name resolves
to a symbol can be reflected only by re-@code{read}ing all such
references.

The Scheme48 development environment supports rapid turnaround in
modular program development by allowing mutations to a program's
configuration and giving a clear semantics to such mutation.  The rule
is that variable bindings in a running program are always resolved
according to the current structure and interface bindings, even when
these bindings change as a result of edits to the configuration.  For
example, consider the following:

@lisp
(define-interface foo-interface (export a c))
(define-structure foo foo-interface
  (open scheme)
  (begin (define a 1)
         (define (b x) (+ a x))
         (define (c y) (* (b a) y))))
(define-structure bar (export d)
  (open scheme foo)
  (begin (define (d w) (+ (b w) a))))@end lisp

This program has a bug.  The variable named @code{b}, which is free in
the definition of @code{d}, has no binding in @code{bar}'s package.
Suppose that @code{b} was intended to be exported by @code{foo}, but
was mistakenly omitted.  It is not necessary to re-process @code{bar} or
any of @code{foo}'s other clients at this point.  One need only change
@code{foo-interface} and inform the development system of that change
(using, say, an appropriate Emacs command), and @code{foo}'s binding of
@code{b} will be found when the procedure @code{d} is called and its
reference to @code{b} actually evaluated.

Similarly, it is possible to replace a structure; clients of the old
structure will be modified so that they see bindings from the new one.
Shadowing is also supported in the same way.  Suppose that a client
package @var{C} opens a structure @code{mumble} that exports a name
@code{x}, and @code{mumble}'s implementation obtains the binding of
@code{x} from some other structure @code{frotz}.  @var{C} will see the
binding from @code{frotz}.  If one then alters @code{mumble} so that it
shadows @code{bar}'s binding of @code{x} with a definition of its own,
procedures in @var{C} that refer to @code{x} will subsequently
automatically see @code{mumble}'s definition instead of the one from
@code{frotz} that they saw earlier.

This semantics might appear to require a large amount of computation on
every variable reference: the specified behaviour appears to require
scanning the package's list of opened structures and examining their
interfaces --- on every variable reference evaluated, not just at
compile-time.  However, the development environment uses caching with
cache invalidation to make variable references fast, and most of the
code is invoked only when the virtual machine traps due to a reference
to an undefined variable.

@subsection Listing interfaces

@cindex interfaces
@stindex list-interfaces
The @code{list-interfaces} structure provides a utility for examining
interfaces.  It is usually opened into the config package with
@code{,config ,open list-interfaces} in order to have access to the
structures & interfaces easily.

@deffn procedure list-interface struct-or-interface @returns{} unspecified
Lists all of the bindings exported by @var{struct-or-interface} along
with their @embedref{Static type system, static types}.  For example,

@lisp
> ,config ,open list-interfaces
> ,config (list-interface condvars)
condvar-has-value?        (proc (:condvar) :value)
condvar-value             (proc (:condvar) :value)
condvar?                  (proc (:value) :boolean)
make-condvar              (proc (&rest :value) :condvar)
maybe-commit-and-set-condvar! (proc (:condvar :value) :boolean)
maybe-commit-and-wait-for-condvar (proc (:condvar) :boolean)
set-condvar-has-value?!   (proc (:condvar :value) :unspecific)
set-condvar-value!        (proc (:condvar :value) :unspecific)@end lisp
@end deffn