This is the mail archive of the guile@sourceware.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]

Re: About modules


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
----------------------------------------

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