[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ModuLite: Scheme Module System proposal
Date: Wed, 11 Sep 1996 16:04:18 +0000
From: William D Clinger <will@ccs.neu.edu>
Here are some technical comments on the ModuLite proposal.
Most of these comments are actually questions concerning
aspects that I don't understand.
One of the standard motivations for modules is to provide a
barrier between interface and implementation. (Typically the
interface defines some notion of an abstract type, but it is
not absolutely necessary that this notion of type be enforced
by the module system.) I didn't see this motivation listed
among the goals for either a module system or a library system.
It was an unintentional omission on my part. Modulite does provide
such a barrier through the type `module'.
In http://www-swiss.ai.mit.edu/~jaffer/modulite_4.html,
I don't understand why an environment is an ordered set of
bindings. Ordinarily an environment is an unordered set of
bindings. Why is ordering necessary here?
Order is the mechanism to resolve which binding occludes which when an
identifier is bound in more than one contour.
In http://www-swiss.ai.mit.edu/~jaffer/modulite_5.html,
I don't understand what definitions are being discussed in
Make-module evaluates expression in a scheme report
environment. Definitions occuring at the top level cause
bindings to be created in the binding contour which the call to
make-module creates and returns.
The definitions being discussed are those occuring at top level in the
code being evaluated. These definitions extend their top-level
environment. But that extended top-level environment is not directly
accesible. Those identifiers EXPORTed are collected into a
binding-countour and returned as the MODULE.
If the expression is truly an expression, then it can't contain
any top-level definitions. Does this have to do with the funny
treatment of LOAD, or is the expression allowed to be a body or
definition instead of an expression, or what?
Looking at the R4RS Formal Syntax, I see that I was using the term
`expression' where I should have said `definition'. What I have in
mind is definitions inside a BEGIN:
(begin
(define foo (lambda (x y) ...))
(define bar (lambda (y) ...)))
I also don't understand
Since identifiers bound to modules will not be visible while
evaluating module source, the mechanism for translating module
names to filenames should be part of the scheme report
environment (although not specified in the report).
My purpose was to explain why module and library constructs must be
part of the scheme-report-environment.
In particular, http://www-swiss.ai.mit.edu/~jaffer/modulite_6.html
says
procedure: import-module modu
Modu should be a module as returned by module, make-module,
or load-module. The import-module procedure adds the
bindings from modu to the top level environment. If an
identifier exported from modu already has a top level
binding, that binding is occluded.
Suppose, for example, that module M1 imports module M2, and that
both M1 and M2 contain a top-level definition of X. Since M2 is
not visible when M1 is evaluated (according to text quoted above),
The exported identifiers of M2 will be visible if imported by M1, but
an identifer named M2 bound to a module (or other object) will not be
part of the scheme-report-environment.
the evaluator must resolve references to X within M1 as references
to the X defined by M1. But then that definition of X is to be
occluded by M2 (according to text quoted above). Does that mean
the evaluator made a mistake when it resolved references to X
within M1 as references to the X defined by M1 instead of the X
defined by M2? Or does it mean that references to X within M1
refer to the X defined by M1, but that references to X within
code that imports M1 will see the definition of X within M2
instead of the definition within M1? A "yes" to either question
is problematic.
Hopefully, the explanation above has resolved this.
I too prefer explicit EXPORT to DEFINE-INTERNAL, but I think the
best solution is to be able to set the default either way, with
explicit overriding for particular identifiers.
When an EXPORT statement is present, the only default which makes
sense is non-export. When a DEFINE-INTERNAL statement is present and
EXPORT is not, the only default which makes sense is export. When
neither EXPORT nor DEFINE-INTERNAL statements are present, the only
default which makes sense is export.