This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: About modules
- To: Jim Blandy <jimb at red-bean dot com>
- Subject: Re: About modules
- From: Jost Boekemeier <jostobfe at linux dot zrz dot TU-Berlin dot DE>
- Date: 06 Mar 2000 17:27:55 +0100
- Cc: Neil Jerram <neil at ossau dot uklinux dot net>, guile at sourceware dot cygnus dot com
- References: <87ema5aumx.fsf@zagadka.ping.de> <200003030023.AAA02695@ossau> <m3k8jkvt13.fsf@savonarola.red-bean.com>
Jim Blandy <jimb@red-bean.com> writes:
> > entry in another environment. We still need an observer mechanism,
> > but per-entry rather than per-environment.
> to announce each binding change individually; the code to track that
> seems more complex and error-prone than my proposal. But that's just
> an intuition; I'd be interested in seeing evidence otherwise.
I think these are two pair of shoes. What Neil is really talking
about is (I think) that we need a mechanism to import and observe
only specific bindings from one environment. This would solve
a problem that your proposal currently has: the `conflict-procī.
I think export- and import-environments should be symmetric. An
import-environment may be connected to an export-environment iff
it conforms to its signature [yeah, I know that this is the first
step towards parametric modules -- shame on me...]
----------------------------------------
@subsection Interface Environments
Interface environments are other environment's signatures. They are
used to encapsulate the meta information that environments have or must
conform to.
An @dfn{interface} environment may be used as the public interface for
all environment types; either as an import or an export environment.
Once accessed, it observes specified bindings in one or more environments
and automatically resolvs naming conflicts.
@deffn Primitive make-interface-environment interface
Creates the new interface environment, @var{in}, which can be used by other
environment types to access bindings specified in @var{interface}.
@var{interface} is a list of environments together with a list of
symbols that should be observed in the given environment. A location
tag may be associated with each symbol: @var{immutable-location},
@var{mutable-location}, @var{alias}.
@deffn interface
interface::= environment-type | environment-list
environment-list::= EOL | "(" environment-type binding-list ")" environment-list
binding-list::= EOL | "#f" | "(" location ")" binding-list
location::= symbol | symbol tag-list
tag-list::= EOL | "mutable-location" | "immutable-location" | "(" rename ")"
rename::= "rename" symbol
@end deffn
@var{interface} may be an environment type. In this case the set
of bindings in @var{in} can be viewed as an extension of the set of
bindings exported from @var{interface}. Local bindings in @var{in}
may shadow bindings exported from @var{interface}.
If the binding-list is @code{#f}, the interface-environment will copy
the binding-list from the specified environment. If this environment
is not an interface-environment or does not have a binding-list, Guile
will signal an error.
All bindings in @var{in} are immutable. If you apply
@code{environment-define} or @code{environment-undefine} to @var{in},
Guile will signal an @code{environment:immutable-binding} error.
The set of bindings in @{in} will never change unless you
change the interface with @code{interface-environment-set-interface!}.
@deffn Primitive interface-environment? object
Return @code{#t} if @var{object} is an interface environment, or @code{#f}
otherwise.
@end deffn
@deffn Primitive interface-environment-interface env
Return the computed list of @var{env}'s imported environments and bindings;
@var{env} must be an import env.
@end deffn
@deffn Primitive interface-environment-set-interface! env interface
Change @var{env}'s list of imported bindings/environments to @var{interface}.
@end deffn
Note that neither @dfn{make-interface-environment} nor
@dfn{interface-environment-set-interface!} do resolve name
conflicts until @var{in} is accessed via @code{environment-ref},
@code{environment-fold}, @code{environment-set!},
@code{environment-cell}, observed by calling @code{environment-observe}
or by letting other environments observe it.
@deffn Primitive interface-environment-append-interface! env interface
Append @var{interface} to the interface that @var{env} has and return
the new interface. Unlike @dfn{interface-environment-set-interface!}
using a call to @{interface-environment-append-interface} may fail and
return @code{#f}.
@end deffn
The following example creates an eval-environment together with an
export-, import- and protect-environment:
@example
(define import-env (make-interface-environment (list (list (the-environment) 'a 'b 'c))))
(define eval-env (make-eval-environment (make-leaf-environment) import-env))
(define export-env (make-interface-environment (list (list eval-env 'a 'b 'c 'x 'y 'z))))
(define protect-env (make-interface-environment (list (cons export-env #f) (list eval-env 'p))))
@end example
----------------------------------------