Commit | Line | Data |
---|---|---|
38a93523 NJ |
1 | \input texinfo @c -*-texinfo-*- |
2 | @c %**start of header | |
3 | @setfilename env.info | |
4 | @settitle Top-level Environments in Guile | |
5 | @c %**end of header | |
6 | ||
7 | @setchapternewpage odd | |
8 | ||
9 | @c Changes since Jost's implementation: | |
10 | @c "finite environments" -> "leaf environments" | |
11 | @c "scm_foo_internal" -> "scm_c_foo" | |
12 | ||
13 | @c To do: | |
14 | @c add spec for soft environments | |
15 | ||
16 | @c When merged into the main manual, add cross-references for: | |
17 | @c weak references | |
18 | @c smobs (esp. module's mark and free functions) | |
19 | ||
20 | ||
21 | [[add refs for all conditions signalled]] | |
22 | ||
23 | @ifinfo | |
b3da54d1 | 24 | Copyright 1999, 2006, 2012 Free Software Foundation, Inc. |
38a93523 NJ |
25 | @end ifinfo |
26 | ||
27 | @titlepage | |
28 | @sp 10 | |
29 | @comment The title is printed in a large font. | |
30 | @center @titlefont{Top-level Environments in Guile} | |
31 | ||
32 | @c The following two commands start the copyright page. | |
33 | @page | |
34 | @vskip 0pt plus 1filll | |
35369f45 | 35 | Copyright @copyright{} 1999, 2006 Free Software Foundation, Inc. |
38a93523 NJ |
36 | @end titlepage |
37 | ||
38 | @node Top, Motivation, (dir), (dir) | |
39 | ||
40 | @menu | |
41 | * Motivation:: | |
42 | * Top-Level Environments in Guile:: | |
43 | * Modules:: | |
44 | @end menu | |
45 | ||
46 | @node Motivation, Top-Level Environments in Guile, Top, Top | |
47 | @chapter Motivation | |
48 | ||
49 | @example | |
35369f45 | 50 | $Id: env.texi,v 1.2 2006-04-16 23:05:07 kryde Exp $ |
38a93523 NJ |
51 | @end example |
52 | ||
53 | This is a draft proposal for a new datatype for representing top-level | |
54 | environments in Guile. Upon completion, this proposal will be posted to | |
55 | the mailing list @samp{guile@@cygnus.com} for discussion, revised in | |
56 | light of whatever insights that may produce, and eventually implemented. | |
57 | ||
58 | Note that this is @emph{not} a proposal for a module system; rather, it | |
59 | is a proposal for a data structure which encapsulates the ideas one | |
60 | needs when writing a module system, and, most importantly, a fixed | |
61 | interface which insulates the interpreter from the details of the module | |
62 | system. Using these environments, one could implement any module system | |
63 | one pleased, without changing the interpreter. | |
64 | ||
65 | I hope this text will eventually become a chapter of the Guile manual; | |
66 | thus, the description of environments in written in the present tense, | |
67 | as if it were already implemented, not in the future tense. However, | |
68 | this text does not actually describe the present state of Guile. | |
69 | ||
70 | I'm especially interested in improving the vague, rambling presentation | |
71 | of environments in the section "Modules and Environments". I'm trying | |
72 | to orient the user for the discussion that follows, but I wonder if I'm | |
73 | just confusing the issue. I would appreciate suggestions if they are | |
74 | concrete --- please provide new wording. | |
75 | ||
76 | Note also: I'm trying out a convention I'm considering for use in the | |
77 | manual. When a Scheme procedure which is directly implemented by a C | |
78 | procedure, and both are useful to call from their respective languages, | |
79 | we document the Scheme procedure only, and call it a "Primitive". If a | |
80 | Scheme function is marked as a primitive, you can derive the name of the | |
81 | corresponding C function by changing @code{-} to @code{_}, @code{!} to | |
82 | @code{_x}, @code{?} to @code{_p}, and prepending @code{scm_}. The C | |
ecb87335 | 83 | function's arguments will be all of the Scheme procedure's arguments, |
38a93523 NJ |
84 | both required and optional; if the Scheme procedure takes a ``rest'' |
85 | argument, that will be a final argument to the C function. The C | |
86 | function's arguments, as well as its return type, will be @code{SCM}. | |
87 | Thus, a procedure documented like this: | |
88 | @deffn Primitive set-car! pair value | |
89 | @end deffn | |
90 | ||
91 | has a corresponding C function which would be documented like this: | |
92 | @deftypefn {Libguile function} SCM scm_set_car_x (SCM @var{pair}, SCM @var{value}) | |
93 | @end deftypefn | |
94 | ||
95 | The hope is that this will be an uncluttered way to document both the C | |
96 | and Scheme interfaces, without unduly confusing users interested only in | |
97 | the Scheme level. | |
98 | ||
99 | When there is a C function which provides the same functionality as a | |
100 | primitive, but with a different interface tailored for C's needs, it | |
101 | usually has the same name as the primitive's C function, but with the | |
102 | prefix @code{scm_c_} instead of simply @code{scm_}. Thus, | |
103 | @code{scm_c_environment_ref} is almost identical to | |
104 | @code{scm_environment_ref}, except that it indicates an unbound variable | |
105 | in a manner friendlier to C code. | |
106 | ||
107 | ||
108 | ||
109 | @node Top-Level Environments in Guile, Modules, Motivation, Top | |
110 | @chapter Top-Level Environments in Guile | |
111 | ||
112 | In Guile, an environment is a mapping from symbols onto variables, and | |
113 | a variable is a location containing a value. Guile uses the datatype | |
114 | described here to represent its top-level environments. | |
115 | ||
116 | ||
117 | @menu | |
118 | * Modules and Environments:: Modules are environments, with bookkeeping. | |
119 | * Common Environment Operations:: Looking up bindings, creating bindings, etc. | |
120 | * Standard Environment Types:: Guile has some fundamental environment types. | |
121 | * Implementing Environments:: You can extend Guile with new kinds of | |
122 | environments. | |
123 | * Switching to Environments:: Changes needed to today's Guile to | |
124 | implement the features described here. | |
125 | @end menu | |
126 | ||
127 | @node Modules and Environments, Common Environment Operations, Top-Level Environments in Guile, Top-Level Environments in Guile | |
128 | @section Modules and Environments | |
129 | ||
130 | Guile distinguishes between environments and modules. A module is a | |
131 | unit of code sharing; it has a name, like @code{(math random)}, an | |
132 | implementation (e.g., Scheme source code, a dynamically linked library, | |
133 | or a set of primitives built into Guile), and finally, an environment | |
134 | containing the definitions which the module exports for its users. | |
135 | ||
136 | An environment, by contrast, is simply an abstract data type | |
137 | representing a mapping from symbols onto variables which the Guile | |
138 | interpreter uses to look up top-level definitions. The @code{eval} | |
139 | procedure interprets its first argument, an expression, in the context | |
140 | of its second argument, an environment. | |
141 | ||
142 | Guile uses environments to implement its module system. A module | |
143 | created by loading Scheme code might be built from several environments. | |
144 | In addition to the environment of exported definitions, such a module | |
145 | might have an internal top-level environment, containing both exported | |
146 | and private definitions, and perhaps environments for imported | |
147 | definitions alone and local definitions alone. | |
148 | ||
149 | The interface described here includes a full set of functions for | |
150 | mutating environments, and the system goes to some length to maintain | |
151 | its consistency as environments' bindings change. This is necessary | |
152 | because Guile is an interactive system. The user may create new | |
153 | definitions or modify and reload modules while Guile is running; the | |
154 | system should handle these changes in a consistent and predictable way. | |
155 | ||
156 | A typical Guile system will have several distinct top-level | |
157 | environments. (This is why we call them ``top-level'', and not | |
158 | ``global''.) For example, consider the following fragment of an | |
159 | interactive Guile session: | |
160 | ||
161 | @example | |
162 | guile> (use-modules (ice-9 regex)) | |
163 | guile> (define pattern "^(..+)\\1+$") | |
164 | guile> (string-match pattern "xxxx") | |
165 | #("xxxx" (0 . 4) (0 . 2)) | |
166 | guile> (string-match pattern "xxxxx") | |
167 | #f | |
168 | guile> | |
169 | @end example | |
170 | @noindent | |
171 | Guile evaluates the expressions the user types in a top-level | |
172 | environment reserved for that purpose; the definition of @code{pattern} | |
173 | goes there. That environment is distinct from the one holding the | |
174 | private definitions of the @code{(ice-9 regex)} module. At the Guile | |
175 | prompt, the user does not see the module's private definitions, and the | |
176 | module is unaffected by definitions the user makes at the prompt. The | |
177 | @code{use-modules} form copies the module's public bindings into the | |
178 | user's environment. | |
179 | ||
180 | All Scheme evaluation takes place with respect to some top-level | |
181 | environment. Just as the procedure created by a @code{lambda} form | |
182 | closes over any local scopes surrounding that form, it also closes over | |
183 | the surrounding top-level environment. Thus, since the | |
184 | @code{string-match} procedure is defined in the @code{(ice-9 regex)} | |
185 | module, it closes over that module's top-level environment. Thus, when | |
186 | the user calls @code{string-match} from the Guile prompt, any free | |
187 | variables in @code{string-match}'s definition are resolved with respect | |
188 | to the module's top-level environment, not the user's. | |
189 | ||
190 | Although the Guile interaction loop maintains a ``current'' top-level | |
191 | environment in which it evaluates the user's input, it would be | |
192 | misleading to extend the concept of a ``current top-level environment'' | |
193 | to the system as a whole. Each procedure closes over its own top-level | |
194 | environment, in which that procedure will find bindings for its free | |
195 | variables. Thus, the top-level environment in force at any given time | |
196 | depends on the procedure Guile happens to be executing. The global | |
197 | ``current'' environment is a figment of the interaction loop's | |
198 | imagination. | |
199 | ||
200 | Since environments provide all the operations the Guile interpreter | |
201 | needs to evaluate code, they effectively insulate the interpreter from | |
202 | the details of the module system. Without changing the interpreter, you | |
203 | can implement any module system you like, as long as its efforts produce | |
204 | an environment object the interpreter can consult. | |
205 | ||
206 | Finally, environments may prove a convenient way for Guile to access the | |
b3da54d1 | 207 | features of other systems. For example, one might export The GIMP's |
38a93523 NJ |
208 | Procedural Database to Guile as a custom environment type; this |
209 | environment could create Scheme procedure objects corresponding to GIMP | |
210 | procedures, as the user referenced them. | |
211 | ||
212 | ||
213 | @node Common Environment Operations, Standard Environment Types, Modules and Environments, Top-Level Environments in Guile | |
214 | @section Common Environment Operations | |
215 | ||
216 | This section describes the common set of operations that all environment | |
217 | objects support. To create an environment object, or to perform an | |
218 | operation specific to a particular kind of environment, see | |
219 | @ref{Standard Environment Types}. | |
220 | ||
221 | In this section, the following names for formal parameters imply that | |
222 | the actual parameters must have a certain type: | |
223 | ||
224 | @table @var | |
225 | ||
226 | @item env | |
227 | an environment | |
228 | ||
229 | @item symbol | |
230 | a symbol | |
231 | ||
232 | @item proc | |
233 | a procedure | |
234 | ||
235 | @item value | |
236 | @itemx object | |
237 | an arbitrary Scheme value | |
238 | ||
239 | @end table | |
240 | ||
241 | ||
242 | @menu | |
243 | * Examining Environments:: | |
244 | * Changing Environments:: | |
245 | * Caching Environment Lookups:: | |
246 | * Observing Changes to Environments :: | |
247 | * Environment Errors:: | |
248 | @end menu | |
249 | ||
250 | @node Examining Environments, Changing Environments, Common Environment Operations, Common Environment Operations | |
251 | @subsection Examining Environments | |
252 | ||
253 | @deffn Primitive environment? object | |
254 | Return @code{#t} if @var{object} is an environment, or @code{#f} otherwise. | |
255 | @end deffn | |
256 | ||
257 | @deffn Primitive environment-ref env symbol | |
258 | Return the value of the location bound to @var{symbol} in @var{env}. | |
259 | If @var{symbol} is unbound in @var{env}, signal an @code{environment:unbound} | |
260 | error (@pxref{Environment Errors}). | |
261 | @end deffn | |
262 | ||
263 | @deffn Primitive environment-bound? env symbol | |
264 | Return @code{#t} if @var{symbol} is bound in @var{env}, or @code{#f} | |
265 | otherwise. | |
266 | @end deffn | |
267 | ||
268 | @deffn Primitive environment-fold env proc init | |
269 | Iterate over all the bindings in an environment, accumulating some value. | |
270 | ||
271 | For each binding in @var{env}, apply @var{proc} to the symbol bound, its | |
272 | value, and the result from the previous application of @var{proc}. Use | |
273 | @var{init} as @var{proc}'s third argument the first time @var{proc} is | |
274 | applied. | |
275 | ||
276 | If @var{env} contains no bindings, this function simply returns @var{init}. | |
277 | ||
278 | If @var{env} binds the symbol @var{sym1} to the value @var{val1}, | |
279 | @var{sym2} to @var{val2}, and so on, then this procedure computes: | |
280 | @example | |
281 | (@var{proc} @var{sym1} @var{val1} | |
282 | (@var{proc} @var{sym2} @var{val2} | |
283 | ... | |
284 | (@var{proc} @var{symn} @var{valn} | |
285 | @var{init}))) | |
286 | @end example | |
287 | ||
288 | Each binding in @var{env} is processed at most once. | |
289 | @code{environment-fold} makes no guarantees about the order in which the | |
290 | bindings are processed. | |
291 | ||
292 | If @var{env} is not modified while the iteration is taking place, | |
293 | @code{environment-fold} will apply @var{proc} to each binding in | |
294 | @var{env} exactly once. | |
295 | ||
296 | If @var{env} is modified while the iteration is taking place, we need to | |
297 | be more subtle in describing @code{environment-fold}'s behavior. | |
298 | @code{environment-fold} repeatedly applies @var{proc} to a binding which | |
299 | was present in @var{env} when @code{environment-fold} was invoked and is | |
300 | still present in @var{env}, until there are no such bindings remaining. | |
301 | (If no mutations take place, this definition is equivalent to the | |
302 | simpler one given above.) By this definition, bindings added during the | |
303 | iteration will not be passed to @var{proc}. | |
304 | ||
305 | Here is a function which, given an environment, constructs an | |
306 | association list representing that environment's bindings, using | |
307 | @code{environment-fold}: | |
308 | @example | |
309 | (define (environment->alist env) | |
310 | (environment-fold env | |
311 | (lambda (sym val tail) | |
312 | (cons (cons sym val) tail)) | |
313 | '())) | |
314 | @end example | |
315 | @end deffn | |
316 | ||
317 | @deftypefn {Libguile macro} int SCM_ENVP (@var{object}) | |
318 | Return non-zero if @var{object} is an environment. | |
319 | @end deftypefn | |
320 | ||
321 | @deftypefn {Libguile function} SCM scm_c_environment_ref (SCM @var{env}, SCM @var{symbol}) | |
322 | This C function is identical to @code{environment-ref}, except that if | |
323 | @var{symbol} is unbound in @var{env}, it returns the value | |
324 | @code{SCM_UNDEFINED}, instead of signalling an error. | |
325 | @end deftypefn | |
326 | ||
327 | @deftypefn {Libguile function} SCM scm_c_environment_fold (SCM @var{env}, scm_environment_folder *@var{proc}, SCM @var{data}, SCM @var{init}) | |
328 | This is the C-level analog of @code{environment-fold}. For each binding in | |
329 | @var{env}, make the call: | |
330 | @example | |
331 | (*@var{proc}) (@var{data}, @var{symbol}, @var{value}, @var{previous}) | |
332 | @end example | |
333 | @noindent | |
334 | where @var{previous} is the value returned from the last call to | |
335 | @code{*@var{proc}}, or @var{init} for the first call. If @var{env} | |
336 | contains no bindings, return @var{init}. | |
337 | @end deftypefn | |
338 | ||
339 | @deftp {Libguile data type} scm_environment_folder SCM (SCM @var{data}, SCM @var{symbol}, SCM @var{value}, SCM @var{tail}) | |
340 | The type of a folding function to pass to @code{scm_c_environment_fold}. | |
341 | @end deftp | |
342 | ||
343 | ||
344 | @node Changing Environments, Caching Environment Lookups, Examining Environments, Common Environment Operations | |
345 | @subsection Changing Environments | |
346 | ||
347 | Here are functions for changing symbols' bindings and values. | |
348 | ||
349 | Although it is common to say that an environment binds a symbol to a | |
350 | value, this is not quite accurate; an environment binds a symbol to a | |
351 | location, and the location contains a value. In the descriptions below, | |
352 | we will try to make clear how each function affects bindings and | |
353 | locations. | |
354 | ||
355 | Note that some environments may contain some immutable bindings, or may | |
356 | bind symbols to immutable locations. If you attempt to change an | |
357 | immutable binding or value, these functions will signal an | |
358 | @code{environment:immutable-binding} or | |
359 | @code{environment:immutable-location} error. However, simply because a | |
360 | binding cannot be changed via these functions does @emph{not} imply that | |
361 | it is constant. Mechanisms outside the scope of this section (say, | |
362 | re-loading a module's source code) may change a binding or value which | |
363 | is immutable via these functions. | |
364 | ||
365 | @deffn Primitive environment-define env symbol value | |
366 | Bind @var{symbol} to a new location containing @var{value} in @var{env}. | |
367 | If @var{symbol} is already bound to another location in @var{env}, that | |
368 | binding is replaced. The new binding and location are both mutable. | |
369 | The return value is unspecified. | |
370 | ||
371 | If @var{symbol} is already bound in @var{env}, and the binding is | |
372 | immutable, signal an @code{environment:immutable-binding} error. | |
373 | @end deffn | |
374 | ||
375 | @deffn Primitive environment-undefine env symbol | |
376 | Remove any binding for @var{symbol} from @var{env}. If @var{symbol} is | |
377 | unbound in @var{env}, do nothing. The return value is unspecified. | |
378 | ||
379 | If @var{symbol} is already bound in @var{env}, and the binding is | |
380 | immutable, signal an @code{environment:immutable-binding} error. | |
381 | @end deffn | |
382 | ||
383 | @deffn Primitive environment-set! env symbol value | |
384 | If @var{env} binds @var{symbol} to some location, change that location's | |
385 | value to @var{value}. The return value is unspecified. | |
386 | ||
387 | If @var{symbol} is not bound in @var{env}, signal an | |
388 | @code{environment:unbound} error. If @var{env} binds @var{symbol} to an | |
389 | immutable location, signal an @code{environment:immutable-location} | |
390 | error. | |
391 | @end deffn | |
392 | ||
393 | ||
394 | @node Caching Environment Lookups, Observing Changes to Environments , Changing Environments, Common Environment Operations | |
395 | @subsection Caching Environment Lookups | |
396 | ||
397 | Some applications refer to variables' values so frequently that the | |
398 | overhead of @code{environment-ref} and @code{environment-set!} is | |
399 | unacceptable. For example, variable reference speed is a critical | |
400 | factor in the performance of the Guile interpreter itself. If an | |
401 | application can tolerate some additional complexity, the | |
402 | @code{environment-cell} function described here can provide very | |
403 | efficient access to variable values. | |
404 | ||
405 | In the Guile interpreter, most variables are represented by pairs; the | |
406 | @sc{cdr} of the pair holds the variable's value. Thus, a variable | |
407 | reference corresponds to taking the @sc{cdr} of one of these pairs, and | |
408 | setting a variable corresponds to a @code{set-cdr!} operation. A pair | |
409 | used to represent a variable's value in this manner is called a | |
410 | @dfn{value cell}. Value cells represent the ``locations'' to which | |
411 | environments bind symbols. | |
412 | ||
413 | The @code{environment-cell} function returns the value cell bound to a | |
414 | symbol. For example, an interpreter might make the call | |
415 | @code{(environment-cell @var{env} @var{symbol} #t)} to find the value | |
416 | cell which @var{env} binds to @var{symbol}, and then use @code{cdr} and | |
417 | @code{set-cdr!} to reference and assign to that variable, instead of | |
418 | calling @code{environment-ref} or @var{environment-set!} for each | |
419 | variable reference. | |
420 | ||
421 | There are a few caveats that apply here: | |
422 | ||
423 | @itemize @bullet | |
424 | ||
425 | @item | |
426 | Environments are not required to represent variables' values using value | |
427 | cells. An environment is free to return @code{#f} in response to a | |
428 | request for a symbol's value cell; in this case, the caller must use | |
429 | @code{environment-ref} and @code{environment-set!} to manipulate the | |
430 | variable. | |
431 | ||
432 | @item | |
433 | An environment's binding for a symbol may change. For example, the user | |
434 | could override an imported variable with a local definition, associating | |
435 | a new value cell with that symbol. If an interpreter has used | |
436 | @code{environment-cell} to obtain the variable's value cell, it no | |
437 | longer needs to use @code{environment-ref} and @code{environment-set!} | |
438 | to access the variable, and it may not see the new binding. | |
439 | ||
440 | Thus, code which uses @code{environment-cell} should almost always use | |
441 | @code{environment-observe} to track changes to the symbol's binding; | |
442 | this is the additional complexity hinted at above. @xref{Observing | |
443 | Changes to Environments}. | |
444 | ||
445 | @item | |
446 | Some variables should be immutable. If a program uses | |
447 | @code{environment-cell} to obtain the value cell of such a variable, | |
448 | then it is impossible for the environment to prevent the program from | |
449 | changing the variable's value, using @code{set-cdr!}. However, this is | |
450 | discouraged; it is probably better to redesign the interface than to | |
451 | disregard such a request. To make it easy for programs to honor the | |
452 | immutability of a variable, @code{environment-cell} takes an argument | |
453 | indicating whether the caller intends to mutate the cell's value; if | |
454 | this argument is true, then @code{environment-cell} signals an | |
455 | @code{environment:immutable-location} error. | |
456 | ||
457 | Programs should therefore make separate calls to @code{environment-cell} | |
458 | to obtain value cells for reference and for assignment. It is incorrect | |
459 | for a program to call @code{environment-cell} once to obtain a value | |
460 | cell, and then use that cell for both reference and mutation. | |
461 | ||
462 | @end itemize | |
463 | ||
464 | @deffn Primitive environment-cell env symbol for-write | |
465 | Return the value cell which @var{env} binds to @var{symbol}, or | |
466 | @code{#f} if the binding does not live in a value cell. | |
467 | ||
468 | The argument @var{for-write} indicates whether the caller intends to | |
469 | modify the variable's value by mutating the value cell. If the variable | |
470 | is immutable, then @code{environment-cell} signals an | |
471 | @code{environment:immutable-location} error. | |
472 | ||
473 | If @var{symbol} is unbound in @var{env}, signal an @code{environment:unbound} | |
474 | error. | |
475 | ||
476 | If you use this function, you should consider using | |
477 | @code{environment-observe}, to be notified when @code{symbol} gets | |
478 | re-bound to a new value cell, or becomes undefined. | |
479 | @end deffn | |
480 | ||
481 | @deftypefn {Libguile function} SCM scm_c_environment_cell (SCM @var{env}, SCM @var{symbol}, int for_write) | |
482 | This C function is identical to @code{environment-cell}, except that if | |
483 | @var{symbol} is unbound in @var{env}, it returns the value | |
484 | @code{SCM_UNDEFINED}, instead of signalling an error. | |
485 | @end deftypefn | |
486 | ||
487 | [[After we have some experience using this, we may find that we want to | |
488 | be able to explicitly ask questions like, "Is this variable mutable?" | |
489 | without the annoyance of error handling. But maybe this is fine.]] | |
490 | ||
491 | ||
492 | @node Observing Changes to Environments , Environment Errors, Caching Environment Lookups, Common Environment Operations | |
493 | @subsection Observing Changes to Environments | |
494 | ||
495 | The procedures described here allow you to add and remove @dfn{observing | |
496 | procedures} for an environment. | |
497 | ||
498 | ||
499 | @menu | |
500 | * Registering Observing Procedures:: | |
501 | * Observations and Garbage Collection:: | |
502 | * Observing Environments from C Code:: | |
503 | @end menu | |
504 | ||
505 | @node Registering Observing Procedures, Observations and Garbage Collection, Observing Changes to Environments , Observing Changes to Environments | |
506 | @subsubsection Registering Observing Procedures | |
507 | ||
508 | A program may register an @dfn{observing procedure} for an environment, | |
509 | which will be called whenever a binding in a particular environment | |
510 | changes. For example, if the user changes a module's source code and | |
511 | re-loads the module, other parts of the system may want to throw away | |
512 | information they have cached about the bindings of the older version of | |
513 | the module. To support this, each environment retains a set of | |
514 | observing procedures which it will invoke whenever its bindings change. | |
515 | We say that these procedures @dfn{observe} the environment's bindings. | |
516 | You can register new observing procedures for an environment using | |
517 | @code{environment-observe}. | |
518 | ||
519 | @deffn Primitive environment-observe env proc | |
520 | Whenever @var{env}'s bindings change, apply @var{proc} to @var{env}. | |
521 | ||
522 | This function returns an object, @var{token}, which you can pass to | |
523 | @code{environment-unobserve} to remove @var{proc} from the set of | |
524 | procedures observing @var{env}. The type and value of @var{token} is | |
525 | unspecified. | |
526 | @end deffn | |
527 | ||
528 | @deffn Primitive environment-unobserve token | |
529 | Cancel the observation request which returned the value @var{token}. | |
530 | The return value is unspecified. | |
531 | ||
532 | If a call @code{(environment-observe @var{env} @var{proc})} returns | |
533 | @var{token}, then the call @code{(environment-unobserve @var{token})} | |
534 | will cause @var{proc} to no longer be called when @var{env}'s bindings | |
535 | change. | |
536 | @end deffn | |
537 | ||
538 | There are some limitations on observation: | |
539 | @itemize @bullet | |
540 | @item | |
541 | These procedures do not allow you to observe specific bindings; you | |
542 | can only observe an entire environment. | |
543 | @item | |
544 | These procedures observe bindings, not locations. There is no way | |
545 | to receive notification when a location's value changes, using these | |
546 | procedures. | |
547 | @item | |
548 | These procedures do not promise to call the observing procedure for each | |
549 | individual binding change. However, if multiple bindings do change | |
550 | between calls to the observing procedure, those changes will appear | |
551 | atomic to the entire system, not just to a few observing procedures. | |
552 | @item | |
553 | Since a single environment may have several procedures observing it, a | |
554 | correct design obviously may not assume that nothing else in the system | |
555 | has yet observed a given change. | |
556 | @end itemize | |
557 | ||
558 | (One weakness of this observation architecture is that observing | |
559 | procedures make no promises to the observer. That's fine if you're just | |
560 | trying to implement an accurate cache, but too weak to implement things | |
561 | that walk the environment tree.) | |
562 | ||
563 | @node Observations and Garbage Collection, Observing Environments from C Code, Registering Observing Procedures, Observing Changes to Environments | |
564 | @subsubsection Observations and Garbage Collection | |
565 | ||
566 | When writing observing procedures, pay close attention to garbage | |
567 | collection issues. If you use @code{environment-observe} to register | |
568 | observing procedures for an environment, the environment will hold a | |
569 | reference to those procedures; while that environment is alive, its | |
570 | observing procedures will live, as will any data they close over. If | |
571 | this is not appropriate, you can use the @code{environment-observe-weak} | |
572 | procedure to create a weak reference from the environment to the | |
573 | observing procedure. | |
574 | ||
575 | For example, suppose an interpreter uses @code{environment-cell} to | |
576 | reference variables efficiently, as described above in @ref{Caching | |
577 | Environment Lookups}. That interpreter must register observing | |
578 | procedures to track changes to the environment. If those procedures | |
579 | retain any reference to the data structure representing the program | |
580 | being interpreted, then that structure cannot be collected as long as | |
581 | the observed environment lives. This is almost certainly incorrect --- | |
582 | if there are no other references to the structure, it can never be | |
583 | invoked, so it should be collected. In this case, the interpreter | |
584 | should register its observing procedure using | |
585 | @code{environment-observe-weak}, and retain a pointer to it from the | |
586 | code it updates. Thus, when the code is no longer referenced elsewhere | |
587 | in the system, the weak link will be broken, and Guile will collect the | |
588 | code (and its observing procedure). | |
589 | ||
590 | @deffn Primitive environment-observe-weak env proc | |
591 | This function is the same as @code{environment-observe}, except that the | |
592 | reference @var{env} retains to @var{proc} is a weak reference. This | |
593 | means that, if there are no other live, non-weak references to | |
594 | @var{proc}, it will be garbage-collected, and dropped from @var{env}'s | |
595 | list of observing procedures. | |
596 | @end deffn | |
597 | ||
598 | ||
599 | @node Observing Environments from C Code, , Observations and Garbage Collection, Observing Changes to Environments | |
600 | @subsubsection Observing Environments from C Code | |
601 | ||
602 | It is also possible to write code that observes an environment in C. | |
603 | The @code{scm_c_environment_observe} function registers a C | |
604 | function to observe an environment. The typedef | |
605 | @code{scm_environment_observer} is the type a C observer function must | |
606 | have. | |
607 | ||
608 | @deftypefn {Libguile function} SCM scm_c_environment_observe (SCM @var{env}, scm_environment_observer *proc, SCM @var{data}, int weak_p) | |
609 | This is the C-level analog of the Scheme function | |
610 | @code{environment-observe}. Whenever @var{env}'s bindings change, call | |
611 | the function @var{proc}, passing it @var{env} and @var{data}. If | |
612 | @var{weak_p} is non-zero, @var{env} will retain only a weak reference to | |
613 | @var{data}, and if @var{data} is garbage collected, the entire | |
614 | observation will be dropped. | |
615 | ||
616 | This function returns a token, with the same meaning as those returned | |
617 | by @code{environment-observe}. | |
618 | @end deftypefn | |
619 | ||
620 | @deftp {Libguile data type} scm_environment_observer void (SCM @var{env}, SCM @var{data}) | |
621 | The type for observing functions written in C. A function meant to be | |
622 | passed to @code{scm_c_environment_observe} should have the type | |
623 | @code{scm_environment_observer}. | |
624 | @end deftp | |
625 | ||
626 | Note that, like all other primitives, @code{environment-observe} is also | |
627 | available from C, under the name @code{scm_environment_observe}. | |
628 | ||
629 | ||
630 | @node Environment Errors, , Observing Changes to Environments , Common Environment Operations | |
631 | @subsection Environment Errors | |
632 | ||
633 | Here are the error conditions signalled by the environment routines | |
634 | described above. In these conditions, @var{func} is a string naming a | |
635 | particular procedure. | |
636 | ||
637 | @deffn Condition environment:unbound func message args env symbol | |
638 | By calling @var{func}, the program attempted to retrieve the value of | |
639 | @var{symbol} in @var{env}, but @var{symbol} is unbound in @var{env}. | |
640 | @end deffn | |
641 | ||
642 | @deffn Condition environment:immutable-binding func message args env symbol | |
643 | By calling @var{func}, the program attempted to change the binding of | |
644 | @var{symbol} in @var{env}, but that binding is immutable. | |
645 | @end deffn | |
646 | ||
647 | @deffn Condition environment:immutable-location func message args env symbol | |
648 | By calling @var{func}, the program attempted to change the value of | |
649 | the location to which @var{symbol} is bound in @var{env}, but that | |
650 | location is immutable. | |
651 | @end deffn | |
652 | ||
653 | ||
654 | @node Standard Environment Types, Implementing Environments, Common Environment Operations, Top-Level Environments in Guile | |
655 | @section Standard Environment Types | |
656 | ||
657 | Guile supports several different kinds of environments. The operations | |
658 | described above are actually only the common functionality provided by | |
659 | all the members of a family of environment types, each designed for a | |
660 | separate purpose. | |
661 | ||
662 | Each environment type has a constructor procedure for building elements | |
663 | of that type, and extends the set of common operations with its own | |
664 | procedures, providing specialized functions. For an example of how | |
665 | these environment types work together, see @ref{Modules of Interpreted | |
666 | Scheme Code}. | |
667 | ||
668 | Guile allows users to define their own environment types. Given a set | |
669 | of procedures that implement the common environment operations, Guile | |
670 | will construct a new environment object based on those procedures. | |
671 | ||
672 | @menu | |
673 | * Leaf Environments:: A simple set of bindings. | |
674 | * Eval Environments:: Local definitions, shadowing | |
675 | imported definitions. | |
676 | * Import Environments:: The union of a list of environments. | |
677 | * Export Environments:: A selected subset of an environment. | |
678 | * General Environments:: Environments implemented by user | |
679 | functions. | |
680 | @end menu | |
681 | ||
682 | @node Leaf Environments, Eval Environments, Standard Environment Types, Standard Environment Types | |
683 | @subsection Leaf Environments | |
684 | ||
685 | A @dfn{leaf} environment is simply a mutable set of definitions. A mutable | |
686 | environment supports no operations beyond the common set. | |
687 | ||
688 | @deffn Primitive make-leaf-environment | |
689 | Create a new leaf environment, containing no bindings. All bindings | |
690 | and locations in the new environment are mutable. | |
691 | @end deffn | |
692 | ||
693 | @deffn Primitive leaf-environment? object | |
64de6db5 | 694 | Return @code{#t} if @var{object} is a leaf environment, or @code{#f} |
38a93523 NJ |
695 | otherwise. |
696 | @end deffn | |
697 | ||
698 | ||
699 | In Guile, each module of interpreted Scheme code uses a leaf | |
700 | environment to hold the definitions made in that module. | |
701 | ||
702 | Leaf environments are so named because their bindings are not computed | |
703 | from the contents of other environments. Most other environment types | |
704 | have no bindings of their own, but compute their binding sets based on | |
705 | those of their operand environments. Thus, the environments in a | |
706 | running Guile system form a tree, with interior nodes computing their | |
707 | contents from their child nodes. Leaf environments are the leaves of | |
708 | such trees. | |
709 | ||
710 | ||
711 | @node Eval Environments, Import Environments, Leaf Environments, Standard Environment Types | |
712 | @subsection Eval Environments | |
713 | ||
714 | A module's source code refers to definitions imported from other | |
715 | modules, and definitions made within itself. An @dfn{eval} environment | |
716 | combines two environments --- a @dfn{local} environment and an | |
717 | @dfn{imported} environment --- to produce a new environment in which | |
718 | both sorts of references can be resolved. | |
719 | ||
720 | @deffn Primitive make-eval-environment local imported | |
721 | Return a new environment object @var{eval} whose bindings are the union | |
722 | of the bindings in the environments @var{local} and @var{imported}, with | |
723 | bindings from @var{local} taking precedence. Definitions made in | |
724 | @var{eval} are placed in @var{local}. | |
725 | ||
726 | Applying @code{environment-define} or @code{environment-undefine} to | |
727 | @var{eval} has the same effect as applying the procedure to @var{local}. | |
728 | This means that applying @code{environment-undefine} to a symbol bound | |
729 | in @var{imported} and free in @var{local} has no effect on the bindings | |
730 | visible in @var{eval}, which may be surprising. | |
731 | ||
732 | Note that @var{eval} incorporates @var{local} and @var{imported} | |
733 | @emph{by reference} --- if, after creating @var{eval}, the program | |
734 | changes the bindings of @var{local} or @var{imported}, those changes | |
735 | will be visible in @var{eval}. | |
736 | ||
737 | Since most Scheme evaluation takes place in @var{eval} environments, | |
ecb87335 | 738 | they transparently cache the bindings received from @var{local} and |
38a93523 NJ |
739 | @var{imported}. Thus, the first time the program looks up a symbol in |
740 | @var{eval}, @var{eval} may make calls to @var{local} or @var{imported} | |
741 | to find their bindings, but subsequent references to that symbol will be | |
742 | as fast as references to bindings in leaf environments. | |
743 | ||
744 | In typical use, @var{local} will be a leaf environment, and | |
745 | @var{imported} will be an import environment, described below. | |
746 | @end deffn | |
747 | ||
748 | @deffn Primitive eval-environment? object | |
749 | Return @code{#t} if @var{object} is an eval environment, or @code{#f} | |
750 | otherwise. | |
751 | @end deffn | |
752 | ||
753 | @deffn Primitive eval-environment-local env | |
754 | @deffnx Primitive eval-environment-imported env | |
755 | Return the @var{local} or @var{imported} environment of @var{env}; | |
756 | @var{env} must be an eval environment. | |
757 | @end deffn | |
758 | ||
759 | ||
760 | @node Import Environments, Export Environments, Eval Environments, Standard Environment Types | |
761 | @subsection Import Environments | |
762 | ||
763 | An @dfn{import} environment combines the bindings of a set of | |
764 | argument environments, and checks for naming clashes. | |
765 | ||
766 | @deffn Primitive make-import-environment imports conflict-proc | |
767 | Return a new environment @var{imp} whose bindings are the union of the | |
768 | bindings from the environments in @var{imports}; @var{imports} must be a | |
769 | list of environments. That is, @var{imp} binds @var{symbol} to | |
770 | @var{location} when some element of @var{imports} does. | |
771 | ||
772 | If two different elements of @var{imports} have a binding for the same | |
773 | symbol, apply @var{conflict-proc} to the two environments. If the bindings | |
774 | of any of the @var{imports} ever changes, check for conflicts again. | |
775 | ||
776 | All bindings in @var{imp} are immutable. If you apply | |
777 | @code{environment-define} or @code{environment-undefine} to @var{imp}, | |
778 | Guile will signal an @code{environment:immutable-binding} error. | |
779 | However, notice that the set of bindings in @var{imp} may still change, | |
780 | if one of its imported environments changes. | |
781 | @end deffn | |
782 | ||
783 | @deffn Primitive import-environment? object | |
784 | Return @code{#t} if @var{object} is an import environment, or @code{#f} | |
785 | otherwise. | |
786 | @end deffn | |
787 | ||
788 | @deffn Primitive import-environment-imports env | |
789 | Return the list of @var{env}'s imported environments; @var{env} must be | |
790 | an import env. | |
791 | @end deffn | |
792 | ||
793 | @deffn Primitive import-environment-set-imports! env imports | |
794 | Change @var{env}'s list of imported environments to @var{imports}, and | |
795 | check for conflicts. | |
796 | @end deffn | |
797 | ||
798 | I'm not at all sure about the way @var{conflict-proc} works. I think | |
799 | module systems should warn you if it seems you're likely to get the | |
800 | wrong binding, but exactly how and when those warnings should be | |
801 | generated, I don't know. | |
802 | ||
803 | ||
804 | @node Export Environments, General Environments, Import Environments, Standard Environment Types | |
805 | @subsection Export Environments | |
806 | ||
807 | An export environment restricts an environment a specified set of | |
808 | bindings. | |
809 | ||
810 | @deffn Primitive make-export-environment private signature | |
811 | Return a new environment @var{exp} containing only those bindings in | |
812 | @var{private} whose symbols are present in @var{signature}. The | |
813 | @var{private} argument must be an environment. | |
814 | ||
815 | The environment @var{exp} binds @var{symbol} to @var{location} when | |
816 | @var{env} does, and @var{symbol} is exported by @var{signature}. | |
817 | ||
64de6db5 | 818 | @var{signature} is a list specifying which of the bindings in |
38a93523 NJ |
819 | @var{private} should be visible in @var{exp}. Each element of |
820 | @var{signature} should be a list of the form: | |
821 | @example | |
822 | (@var{symbol} @var{attribute} ...) | |
823 | @end example | |
824 | @noindent | |
825 | where each @var{attribute} is one of the following: | |
826 | @table @asis | |
827 | @item the symbol @code{mutable-location} | |
828 | @var{exp} should treat the location bound to @var{symbol} as mutable. | |
829 | That is, @var{exp} will pass calls to @var{env-set!} or | |
830 | @code{environment-cell} directly through to @var{private}. | |
831 | ||
832 | @item the symbol @code{immutable-location} | |
833 | @var{exp} should treat the location bound to @var{symbol} as immutable. | |
834 | If the program applies @code{environment-set!} to @var{exp} and | |
835 | @var{symbol}, or calls @code{environment-cell} to obtain a writable | |
836 | value cell, @code{environment-set!} will signal an | |
837 | @code{environment:immutable-location} error. | |
838 | ||
839 | Note that, even if an export environment treats a location as immutable, | |
840 | the underlying environment may treat it as mutable, so its value may | |
841 | change. | |
842 | @end table | |
843 | ||
844 | It is an error for an element of @var{signature} to specify both | |
845 | @code{mutable-location} and @code{immutable-location}. If neither is | |
846 | specified, @code{immutable-location} is assumed. | |
847 | ||
848 | As a special case, if an element of @var{signature} is a lone symbol | |
849 | @var{sym}, it is equivalent to an element of the form | |
850 | @code{(@var{sym})}. | |
851 | ||
852 | All bindings in @var{exp} are immutable. If you apply | |
853 | @code{environment-define} or @code{environment-undefine} to @var{exp}, | |
854 | Guile will signal an @code{environment:immutable-binding} error. | |
855 | However, notice that the set of bindings in @var{exp} may still change, | |
856 | if the bindings in @var{private} change. | |
857 | @end deffn | |
858 | ||
859 | @deffn Primitive export-environment? object | |
860 | Return @code{#t} if @var{object} is an export environment, or @code{#f} | |
861 | otherwise. | |
862 | @end deffn | |
863 | ||
864 | @deffn Primitive export-environment-private env | |
865 | @deffnx Primitive export-environment-set-private! env | |
866 | @deffnx Primitive export-environment-signature env | |
867 | @deffnx Primitive export-environment-set-signature! env | |
868 | Accessors and mutators for the private environment and signature of | |
869 | @var{env}; @var{env} must be an export environment. | |
870 | @end deffn | |
871 | ||
872 | ||
873 | @node General Environments, , Export Environments, Standard Environment Types | |
874 | @subsection General Environments | |
875 | ||
876 | [[user provides the procedures]] | |
877 | [[A observers B and C; B observes C; C changes; A should only be | |
878 | notified once, right?]] | |
879 | [[observation loops?]] | |
880 | ||
881 | @node Implementing Environments, Switching to Environments, Standard Environment Types, Top-Level Environments in Guile | |
882 | @section Implementing Environments | |
883 | ||
884 | This section describes how to implement new environment types in Guile. | |
885 | ||
886 | Guile's internal representation of environments allows you to extend | |
887 | Guile with new kinds of environments without modifying Guile itself. | |
888 | Every environment object carries a pointer to a structure of pointers to | |
889 | functions implementing the common operations for that environment. The | |
890 | procedures @code{environment-ref}, @code{environment-set!}, etc. simply | |
891 | find this structure and invoke the appropriate function. | |
892 | ||
893 | [[It would be nice to have an example around here. How about a | |
894 | persistent environment, bound to a directory, where ref and set actually | |
895 | access files? Ref on a directory would return another | |
896 | environment... Hey, let's import my home directory!]] | |
897 | ||
898 | ||
899 | @menu | |
900 | * Environment Function Tables:: | |
901 | * Environment Data:: | |
902 | * Environment Example:: | |
903 | @end menu | |
904 | ||
905 | ||
906 | @node Environment Function Tables, Environment Data, Implementing Environments, Implementing Environments | |
907 | @subsection Environment Function Tables | |
908 | ||
909 | An environment object is a smob whose @sc{cdr} is a pointer to a pointer | |
910 | to a @code{struct environment_funcs}: | |
911 | @example | |
912 | struct environment_funcs @{ | |
913 | SCM (*ref) (SCM self, SCM symbol); | |
914 | SCM (*fold) (SCM self, scm_environment_folder *proc, SCM data, SCM init); | |
915 | void (*define) (SCM self, SCM symbol, SCM value); | |
916 | void (*undefine) (SCM self, SCM symbol); | |
917 | void (*set) (SCM self, SCM symbol, SCM value); | |
918 | SCM (*cell) (SCM self, SCM symbol, int for_write); | |
919 | SCM (*observe) (SCM self, scm_environment_observer *proc, SCM data, int weak_p); | |
920 | void (*unobserve) (SCM self, SCM token); | |
921 | SCM (*mark) (SCM self); | |
922 | scm_sizet (*free) (SCM self); | |
923 | int (*print) (SCM self, SCM port, scm_print_state *pstate); | |
924 | @}; | |
925 | @end example | |
926 | ||
927 | You can use the following macro to access an environment's function table: | |
928 | ||
929 | @deftypefn {Libguile macro} struct environment_funcs *SCM_ENVIRONMENT_FUNCS (@var{env}) | |
930 | Return a pointer to the @code{struct environment_func} for the environment | |
931 | @var{env}. If @var{env} is not an environment object, the behavior of | |
932 | this macro is undefined. | |
933 | @end deftypefn | |
934 | ||
935 | Here is what each element of @var{env_funcs} must do to correctly | |
936 | implement an environment. In all of these calls, @var{self} is the | |
937 | environment whose function is being invoked. | |
938 | ||
939 | @table @code | |
940 | ||
941 | @item SCM ref (SCM @var{self}, SCM @var{symbol}); | |
942 | This function must have the effect described above for the C call: | |
943 | @example | |
944 | scm_c_environment_ref (@var{self}, @var{symbol}) | |
945 | @end example | |
946 | @xref{Examining Environments}. | |
947 | ||
948 | Note that the @code{ref} element of a @code{struct environment_funcs} | |
949 | may be zero if a @code{cell} function is provided. | |
950 | ||
951 | @item SCM fold (SCM self, scm_environment_folder *proc, SCM data, SCM init); | |
952 | This function must have the effect described above for the C call: | |
953 | @example | |
954 | scm_c_environment_fold (@var{self}, @var{proc}, @var{data}, @var{init}) | |
955 | @end example | |
956 | @xref{Examining Environments}. | |
957 | ||
958 | @item void define (SCM self, SCM symbol, SCM value); | |
959 | This function must have the effect described above for the Scheme call: | |
960 | @example | |
961 | (environment-define @var{self} @var{symbol} @var{value}) | |
962 | @end example | |
963 | @xref{Changing Environments}. | |
964 | ||
965 | @item void undefine (SCM self, SCM symbol); | |
966 | This function must have the effect described above for the Scheme call: | |
967 | @example | |
968 | (environment-undefine @var{self} @var{symbol}) | |
969 | @end example | |
970 | @xref{Changing Environments}. | |
971 | ||
972 | @item void set (SCM self, SCM symbol, SCM value); | |
973 | This function must have the effect described above for the Scheme call: | |
974 | @example | |
975 | (environment-set! @var{self} @var{symbol} @var{value}) | |
976 | @end example | |
977 | @xref{Changing Environments}. | |
978 | ||
979 | Note that the @code{set} element of a @code{struct environment_funcs} | |
980 | may be zero if a @code{cell} function is provided. | |
981 | ||
982 | @item SCM cell (SCM self, SCM symbol, int for_write); | |
983 | This function must have the effect described above for the C call: | |
984 | @example | |
985 | scm_c_environment_cell (@var{self}, @var{symbol}) | |
986 | @end example | |
987 | @xref{Caching Environment Lookups}. | |
988 | ||
989 | @item SCM observe (SCM self, scm_environment_observer *proc, SCM data, int weak_p); | |
990 | This function must have the effect described above for the C call: | |
991 | @example | |
992 | scm_c_environment_observe (@var{env}, @var{proc}, @var{data}, @var{weak_p}) | |
993 | @end example | |
994 | @xref{Observing Changes to Environments}. | |
995 | ||
996 | @item void unobserve (SCM self, SCM token); | |
997 | Cancel the request to observe @var{self} that returned @var{token}. | |
998 | @xref{Observing Changes to Environments}. | |
999 | ||
1000 | @item SCM mark (SCM self); | |
1001 | Set the garbage collection mark all Scheme cells referred to by | |
1002 | @var{self}. Assume that @var{self} itself is already marked. Return a | |
1003 | final object to be marked recursively. | |
1004 | ||
1005 | @item scm_sizet free (SCM self); | |
1006 | Free all non-cell storage associated with @var{self}; return the number | |
1007 | of bytes freed that were obtained using @code{scm_must_malloc} or | |
1008 | @code{scm_must_realloc}. | |
1009 | ||
1010 | @item SCM print (SCM self, SCM port, scm_print_state *pstate); | |
1011 | Print an external representation of @var{self} on @var{port}, passing | |
1012 | @var{pstate} to any recursive calls to the object printer. | |
1013 | ||
1014 | @end table | |
1015 | ||
1016 | ||
1017 | @node Environment Data, Environment Example, Environment Function Tables, Implementing Environments | |
1018 | @subsection Environment Data | |
1019 | ||
1020 | When you implement a new environment type, you will likely want to | |
1021 | associate some data of your own design with each environment object. | |
1022 | Since ANSI C promises that casts will safely convert between a pointer | |
1023 | to a structure and a pointer to its first element, you can have the | |
1024 | @sc{cdr} of an environment smob point to your structure, as long as your | |
1025 | structure's first element is a pointer to a @code{struct | |
1026 | environment_funcs}. Then, your code can use the macro below to retrieve | |
1027 | a pointer to the structure, and cast it to the appropriate type. | |
1028 | ||
1029 | @deftypefn {Libguile macro} struct environment_funcs **SCM_ENVIRONMENT_DATA (@var{env}) | |
1030 | Return the @sc{cdr} of @var{env}, as a pointer to a pointer to an | |
1031 | @code{environment_funcs} structure. | |
1032 | @end deftypefn | |
1033 | ||
1034 | @node Environment Example, , Environment Data, Implementing Environments | |
1035 | @subsection Environment Example | |
1036 | ||
1037 | [[perhaps a simple environment based on association lists]] | |
1038 | ||
1039 | ||
1040 | @node Switching to Environments, , Implementing Environments, Top-Level Environments in Guile | |
1041 | @section Switching to Environments | |
1042 | ||
1043 | Here's what we'd need to do to today's Guile to install the system | |
1044 | described above. This work would probably be done on a branch, because | |
1045 | it involves crippling Guile while a lot of work gets done. Also, it | |
1046 | could change the default set of bindings available pretty drastically, | |
1047 | so the next minor release should not contain these changes. | |
1048 | ||
1049 | After each step here, we should have a Guile that we can at least | |
1050 | interact with, perhaps with some limitations. | |
1051 | ||
1052 | @itemize @bullet | |
1053 | ||
1054 | @item | |
1055 | For testing purposes, make an utterly minimal version of | |
8c34cf5b | 1056 | @file{boot-9.scm}: no module system, no R5RS, nothing. I think a simple |
38a93523 NJ |
1057 | REPL is all we need. |
1058 | ||
1059 | @item | |
1060 | Implement the environment datatypes in libguile, and test them using | |
1061 | this utterly minimal system. | |
1062 | ||
1063 | @item | |
1064 | Change the interpreter to use the @code{environment-cell} and | |
1065 | @code{environment-observe} instead of the symbol value slots, | |
1066 | first-class variables, etc. Modify the rest of libguile as necessary to | |
1067 | register all the primitives in a single environment. We'll segregate | |
1068 | them into modules later. | |
1069 | ||
1070 | @item | |
1071 | Reimplement the current module system in terms of environments. It | |
1072 | should still be in Scheme. | |
1073 | ||
1074 | @item | |
1075 | Reintegrate the rest of @file{boot-9.scm}. This might be a good point | |
1076 | to move it into modules. | |
1077 | ||
1078 | @item | |
1079 | Do some profiling and optimization. | |
1080 | ||
1081 | @end itemize | |
1082 | ||
1083 | Once this is done, we can make the following simplifications to Guile: | |
1084 | ||
1085 | @itemize @bullet | |
1086 | ||
1087 | @item | |
1088 | A good portion of symbols.c can go away. Symbols no longer need value | |
ecb87335 | 1089 | slots. The mishmash of @code{scm_sym2ovcell}, |
38a93523 NJ |
1090 | @code{scm_intern_obarray_soft}, etc. can go away. @code{intern} becomes |
1091 | simpler. | |
1092 | ||
1093 | @item | |
1094 | Remove first-class variables: @file{variables.c} and @file{variables.h}. | |
1095 | ||
1096 | @item | |
1097 | Organize the primitives into environments. | |
1098 | ||
1099 | @item | |
1100 | The family of environment types is clearly an abstract class/concrete | |
1101 | subclass arrangement. We should provide GOOPS classes/metaclasses that | |
1102 | make defining new environment types easy and consistent. | |
1103 | ||
1104 | @end itemize | |
1105 | ||
1106 | ||
1107 | ||
1108 | @node Modules, , Top-Level Environments in Guile, Top | |
1109 | @chapter Modules | |
1110 | ||
1111 | The material here is just a sketch. Don't take it too seriously. The | |
1112 | point is that environments allow us to experiment without getting | |
1113 | tangled up with the interpreter. | |
1114 | ||
1115 | @menu | |
1116 | * Modules of Guile Primitives:: | |
1117 | * Modules of Interpreted Scheme Code:: | |
1118 | @end menu | |
1119 | ||
1120 | @node Modules of Guile Primitives, Modules of Interpreted Scheme Code, Modules, Modules | |
1121 | @section Modules of Guile Primitives | |
1122 | ||
1123 | @node Modules of Interpreted Scheme Code, , Modules of Guile Primitives, Modules | |
1124 | @section Modules of Interpreted Scheme Code | |
1125 | ||
1126 | If a module is implemented by interpreted Scheme code, Guile represents | |
1127 | it using several environments: | |
1128 | ||
1129 | @table @asis | |
1130 | ||
1131 | @item the @dfn{local} environment | |
1132 | This environment holds all the definitions made locally by the module, | |
1133 | both public and private. | |
1134 | ||
1135 | @item the @dfn{import} environment | |
1136 | This environment holds all the definitions this module imports from | |
1137 | other modules. | |
1138 | ||
1139 | @item the @dfn{evaluation} environment | |
1140 | This is the environment in which the module's code is actually | |
1141 | evaluated, and the one closed over by the module's procedures, both | |
1142 | public and private. Its bindings are the union of the @var{local} and | |
1143 | @var{import} environments, with local bindings taking precedence. | |
1144 | ||
1145 | @item the @dfn{exported} environment | |
1146 | This environment holds the module's public definitions. This is the | |
1147 | only environment that the module's users have access to. It is the | |
1148 | @var{evaluation} environment, restricted to the set of exported | |
1149 | definitions. | |
1150 | ||
1151 | @end table | |
1152 | ||
1153 | Each of these environments is implemented using a separate environment | |
1154 | type. Some of these types, like the evaluation and import environments, | |
1155 | actually just compute their bindings by consulting other environments; | |
1156 | they have no bindings in their own right. They implement operations | |
1157 | like @code{environment-ref} and @code{environment-define} by passing | |
1158 | them through to the environments from which they are derived. For | |
1159 | example, the evaluation environment will pass definitions through to the | |
1160 | local environment, and search for references and assignments first in | |
1161 | the local environment, and then in the import environment. | |
1162 | ||
1163 | ||
1164 | ||
1165 | @bye |