Date: Fri, 2 Dec 2005 18:21:57 -0800 (PST)
From: bear <xxxxxx@sonic.net>
But I want to point out some simple things that work
in other languages, and point out that this model
does not support them.
(I'm going to assume, since you're responding to my mail, that by
'this model' you mean my (Scheme48-based) model, not the current
SRFI's (MzScheme-based) model.)
In static languages such as C and Pascal, a forward
declaration is often used to state particular properties
about a function or procedure, while leaving the body
of the definition for later (presumably after the
definitions of some of the things it depends on).
In both languages, a procedure or function may have any
number of forward declarations (or the same forward
declaration may be imported multiple times) but only
one definition.
In C in particular, this turned out to facilitate a
very useful pattern. A "header file" with nothing but
forward declarations allows most interdependency problems
to be solved statically, because the forward declarations
facilitate the separated compilation of many different
units. The effect is that with the forward declarations
handy, the compiler knows how to compile calls to particular
functions, even when the definitions of those functions are
not visible. This is very important.
I certainly agree that this can be very important, and this is why I
am proposing a module model that allows for this kind of information
to be obtained from simple static analyses of the module language
without delving into the source code of any modules.
So I look at the "imports" syntax, and I am thinking,
"Here is a forward declaration. Does it contain enough
information to allow a compiler to create an optimized
call to the associated function without being able to
see the function definition?" And the answer is a resounding
no. It contains only namespace control information.
No, the answer is not a resounding 'no.' The answer depends on what
information can be obtained statically from the modules from which
bindings are being imported. In my proposed model, this information
is *always* available to a processor of the module system, in the form
of the interface of the module. Indeed, namespace control information
is only one of the many useful properties of the model I'm proposing,
among which this kind of easy static analysis of module descriptions
also lies.
So I look at the "exports" syntax, and I am thinking,
"okay, here is more namespace control information, but it
is also a specification that, together with the file of
source code, may be used to automatically generate
(implicit) forward declarations usable in the compilation
of other files."
Ignoring macros, you do not need the source file. The interface
contains enough information to know what kind of denotation every
identifier exported by a module implementing the interface will have.
This is sufficient to compile clients of the modules (assuming, again,
that macros are not used, which inherently require static information
to be passed across module compilations).
In the simplest form, there is no more information than whether the
binding is a syntactic binding or a run-time variable binding, but the
EXPORT syntax could be extended to support more information than that
for further compiler optimization. In Scheme48, for example, there is
a simple static type language that can be used to annotate the
identifiers listed in interfaces with their static types; the
interface of the SCHEME module, for instance, might be defined along
these lines:
(define-interface scheme-interface
(export ... (car (proc (:pair) :value)) ...))
(This optional static type language is documented in my unofficial
Scheme48 reference manual, which is available on the web at
<http://mumble.net/~campbell/darcs/s48-refman/> (Texinfo source; I can
supply different formats on request).)