This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

First-class environment proposal


Jim Blandy writes:

 > [...]
 >
 > Modules and Environments
 > ========================

suggestion: rename to "environments and modules".  rationale: state more
fundamental concepts first.

 > [...]
 >
 >    Guile distinguishes between environments and modules.  A module is a
 > unit of code sharing; it has a name, like `(math random)', an
 > implementation (e.g., Scheme source code, a dynamically linked library,
 > or a set of primitives built into Guile), and finally, an environment
 > containing the definitions which the module exports for its users.
 > 
 >    An environment, by contrast, is simply an abstract data type
 > representing a mapping from symbols onto variables which the Guile
 > interpreter uses to look up top-level definitions.  The `eval'
 > procedure interprets its first argument, an expression, in the context
 > of its second argument, an environment.
 > 
 >    Guile uses environments to implement its module system.  A module
 > created by loading Scheme code might be built from several environments.
 > In addition to the environment of exported definitions, such a module
 > might have an internal top-level environment, containing both exported
 > and private definitions, and perhaps environments for imported
 > definitions alone and local definitions alone.

how about:

"Guile uses environments to implement its module system; a module is
built from one or more environments.  For example, in addition to the
environment of exported definitions, a module might have an internal
top-level environment, containing both exported and private definitions,
and perhaps environments for imported definitions alone and local
definitions alone.

Modules also have a name, externally represented like `(math random)',
an implementation, and a long and confusing history with many skeletons
in the closet.  *Note Modules::."

rationale/approach: state relationship at the beginning, elucidate a
little and then slough off details to other doc sections.  :->

 > [...]
 >
 >  - Primitive: env-ref ENV SYMBOL
 >      Return the value of the location bound to SYMBOL in ENV.  If
 >      SYMBOL is unbound in ENV, signal an `env:unbound' error (*note
 >      Environment Errors::.).
 > 
 >  - Primitive: env-bound? ENV SYMBOL
 >      Return `#t' if SYMBOL is bound in ENV, or `#f' otherwise.

how about: "env-sym-ref" and "env-sym-bound?" ?  rationale: since
environments are first-class in this system, maybe these two functions
should specify that symbols are the subject in their name.  as it
stands, it could be confusing.  (one could mistakenly intuit "env-ref"
and "env-bound" to use some kind of global r*g*stry for environments.)
on the other hand, my suggested names are ugly.  :-/

 > [...]
 >
 >    In Guile, most variables are represented by pairs; the CDR of the
 > pair holds the variable's value.  Thus, a variable reference corresponds
 > to taking the CDR of one of these pairs, and setting a variable
 > corresponds to a `set-cdr!' operation.  A pair used to represent a
 > variable's value in this manner is called a "value cell".  Value cells
 > represent the "locations" to which environments bind symbols.
 > 
 >    The `env-cell' function returns the value cell bound to a symbol.
 > For example, an interpreter might make the call `(env-cell ENV SYMBOL
 > #f)' to find the value cell which ENV binds to SYMBOL, and then use
 > `cdr' and `set-cdr!' to reference and assign to that variable, instead
 > of calling `env-ref' or ENV-SET! for each variable reference.

could it be that future guile implementations do not use cells?  if so,
how about saying "env-location" instead of "env-cell"?

 > [...]
 >
 >  - Primitive: make-import-env IMPORTS CONFLICT-PROC
 >      Return a new environment IMP whose bindings are the union of the
 >      bindings from the environments in IMPORTS; IMPORTS must be a list
 >      of environments.  That is, IMP binds SYMBOL to LOCATION iff some
 >      element of IMPORTS does.
 > 
 >      If two different elements of IMPORTS have a binding for the same
 >      symbol, apply CONFLICT-PROC to the two environments.  If the
 >      bindings of any of the IMPORTS ever changes, check for conflicts
 >      again.
 > 
 >      All bindings in IMP are immutable.  If you apply`env-define' or
 >      `env-undefine' to IMP, Guile will signal an
 >      `env:immutable-binding' error.  However, notice that the set of
 >      bindings in IMP may still change, if one of its imported
 >      environments changes.
 > 
 >  - Primitive: import-env? OBJECT
 >      Return `#t' if OBJECT is an import environment, or `#f' otherwise.
 > 
 >  - Primitive: import-env-imports ENV
 >      Return the list of ENV's imported environments; ENV must be an
 >      import env.
 > 
 >  - Primitive: import-env-set-imports! ENV IMPORTS
 >      Change ENV's list of imported environments to IMPORTS, and check
 >      for conflicts.
 > 
 >    I'm not at all sure about the way CONFLICT-PROC works.  I think
 > module systems should warn you if it seems you're likely to get the
 > wrong binding, but exactly how and when those warnings should be
 > generated, I don't know.

how about:

"If two different elements of IMPORTS have a binding for the same
symbol, apply CONFLICT-PROC to WACO BRDAVID BATF.  CONFLICT-PROC must
grant WACO binding to either BRDAVID, BATF or #f.  In no case should
CONFLICT-PROC leave WACO unbound.  If the bindings of any of the IMPORTS
ever changes, check for conflicts again."

or substitute SYMBOL, NATIVE-ENV and INVADING-ENV, respectively.

(sorry, could not resist.  ;-)

 > Export Environments
 > -------------------
 > 
 >    An export environment restricts an environment a specified set of
 > bindings.
 > 
 >  - Primitive: make-export-env PRIVATE SIGNATURE
 >      Return a new environment EXP containing only those bindings in
 >      PRIVATE whose symbols are present in SIGNATURE.  The PRIVATE
 >      argument must be an environment.
 > 
 >      The environment EXP binds SYMBOL to LOCATION iff ENV does, and
                                                         ^^^
---------------------------------------------------------^^^

should be "PRIVATE"?  how about a rewording:

"Each SYMBOL in SIGNATURE that is bound in PRIVATE is bound in EXP."

rationale: drop "LOCATION" since it's not used in the text.


overall, one disclaimer that keeps resurfacing is the actual mutability
of underlying (imported) symbols in contrast to the term "immutable".
this concept should be coalesced into some catch-phrase, maybe "shallow
immutability", and given a document subsection somewhere.  then it's a
matter of reference, etc.

in general, it looks rather spiffy!  can't wait to use this stuff.

thi