mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-02 13:00:26 +02:00
295 lines
8.8 KiB
Text
295 lines
8.8 KiB
Text
@c devel/modules/desgin-notes.texi
|
|
|
|
@c TODO
|
|
@c - distill wishlist, index
|
|
@c - in Findings, characterize current module system wrt wishlist
|
|
|
|
@node Module System Design Notes
|
|
@chapter Module System Design Notes
|
|
|
|
This chapter documents module system design history. At the moment
|
|
(guile-1.5.4, 2002-02-08), the module system is supposedly undergoing
|
|
redesign; the provisional implementation works but has problems, notably
|
|
making compilation difficult.
|
|
|
|
Because module systems design is (was?) an area of active research and
|
|
development in the Scheme community, many different features are possible.
|
|
This section is a historical record of the selection process used by the Guile
|
|
hackers (if one can be discerned).
|
|
|
|
@menu
|
|
* Wishlist::
|
|
* Findings::
|
|
* Selection Criteria::
|
|
* Rationale Statements::
|
|
* Specification::
|
|
@end menu
|
|
|
|
@node Wishlist
|
|
@subsection Wishlist
|
|
|
|
In the guile-related mailing lists of yore, discussion resulted in the
|
|
following desirable traits. Note that some of these contradict each other.
|
|
|
|
@itemize @bullet
|
|
|
|
@item
|
|
support separate compilation
|
|
|
|
@item
|
|
hierarchical module names
|
|
|
|
@item
|
|
support relative references within the module name space (so that a
|
|
module within a package can use a sibling module without knowing the
|
|
prefix of the module name)
|
|
|
|
@item
|
|
support re-use of code (the same implementation can be presented to
|
|
the world through several interfaces)
|
|
|
|
@item
|
|
support individual and group renaming of bindings when using other
|
|
modules
|
|
|
|
@item
|
|
easy to import and re-export entire interfaces (so that a main
|
|
interface in a package can function as a "relay" and publish
|
|
bindings from many modules in the package)
|
|
|
|
@item
|
|
support both variable and syntactic bindings (these should be
|
|
clearly separated, though) and mesh well with hygienic macro
|
|
systems
|
|
|
|
@item
|
|
hygienic implies that we shouldn't need to care to export bindings
|
|
which an exported macro introduces at the point of its use
|
|
|
|
@item
|
|
autoloading
|
|
|
|
@item
|
|
unmemoization protocol
|
|
|
|
@item
|
|
cleanliness
|
|
|
|
A module should be able to be totally clean. There should be no
|
|
need to have *any* extra bindings in a module (a la
|
|
%module-interface or `define-module').
|
|
|
|
Therefore, we should have at least one dedicated "command" or
|
|
"config" or "repl" module.
|
|
|
|
It would probably be a good idea to follow other good Scheme
|
|
interpreters' lead and introduce the ,<command> syntax for walking
|
|
around modules, inspecting things, entering the debugger, etc.
|
|
Such commands can be looked up in this repl module.
|
|
|
|
If we insist on not using ,<command> syntax, we are forced to let
|
|
the module use list consist of a "sticky" part and the rest, where
|
|
the "sticky" part is only available at the repl prompt and not to
|
|
the code within the module, and which follows us when we walk around
|
|
in the system.
|
|
|
|
@item
|
|
well integrated with the translator framework
|
|
|
|
We should be able to say that a module uses a different syntax or
|
|
language.
|
|
|
|
Note here the nice config language of the Scheme48 module system
|
|
where it is possible to separate code from module specification: the
|
|
module specification can use scheme syntax and rest in one file,
|
|
while the module itself can use the syntax of another language.
|
|
|
|
This config language also supports re-use of code in a neat way.
|
|
|
|
@item
|
|
examine connection with object system: how easy is it to support
|
|
Java and other class-centered object systems?
|
|
|
|
@item
|
|
easy to export the same module under several different names
|
|
|
|
@item
|
|
easily supports both compiled and interpreted modules
|
|
|
|
@item
|
|
compiled modules can by dynamically loaded or statically linked in
|
|
(libltdl might provide this automatically)
|
|
|
|
@item
|
|
convenient syntax for referencing bindings in modules that are
|
|
loaded but not used
|
|
|
|
(Assuming this distinction exists.) But maybe group renaming is a better
|
|
solution to a similar class of problems.
|
|
|
|
@item
|
|
ability to unuse a module (and have it get collected when there are
|
|
no more references)
|
|
|
|
@item
|
|
orthoganality between source files, directories and modules. i.e. ability to
|
|
have multiple modules in one source file and/or multiple source files in one
|
|
module
|
|
|
|
@item
|
|
backward compatibility
|
|
|
|
@item
|
|
whenever possible the module's meta-information should be stored
|
|
within the module itself (only possible for scheme files)
|
|
|
|
@item
|
|
the compiler stores the meta-information into a single file and updates it
|
|
accordingly
|
|
|
|
(FIXME: per module, per package, directory?, per project?) This
|
|
meta-information should still be human readable (Sun's EJB use XML for their
|
|
deployment descriptors).
|
|
|
|
@item
|
|
use the file system as module repository
|
|
|
|
Since guile is a GNU project we can expect a GNU (or Unix) environment. That
|
|
means that we should use the file system as the module repository. (This
|
|
would help us avoid modules pointing to files which are pointing to other
|
|
files telling the user "hey, that's me (the module) over there".)
|
|
|
|
@item
|
|
every module has exactly @emph{one} owner who is responsible for the
|
|
module @emph{and} its interface (this contradicts with the "more than one
|
|
interface" concept)
|
|
|
|
@item
|
|
support module collections
|
|
|
|
Provide "packages" with a package scope for people working together on a
|
|
project. In some sense a module is a view on the underlying package.
|
|
|
|
@item
|
|
ability to request (i.e. import or access) complete packages
|
|
|
|
@item
|
|
support module "generations" (or "versions")
|
|
|
|
Whenever a new module fails to handle a request (due to an error) it will be
|
|
replaced by the old version.
|
|
|
|
@item
|
|
help the user to handle exceptions (note: exceptions
|
|
are not errors, see above)
|
|
|
|
@item
|
|
no special configuration language (like @code{,in} etc.)
|
|
|
|
You can always press Control-D to terminate the module's repl and return to
|
|
the config module.
|
|
|
|
@item
|
|
both C and Scheme level interfaces
|
|
|
|
@item
|
|
programming interface to module system primitives
|
|
|
|
One should be able to make customized module systems from the low-level
|
|
interface, as an alternative to using the default module system. The
|
|
default module system should use the same low-level procedures.
|
|
|
|
@item
|
|
Here are some features Keisuke Nishida desires to support his VM/compiler
|
|
[snarfed directly from post <m37l33z0cl.wl@kei.cwru.edu> dated 2001-02-06,
|
|
and requires formatting]:
|
|
|
|
* There is no "current module".
|
|
|
|
* Module variables are globally identified by an identifier
|
|
like "system::core::car".
|
|
|
|
* Bindings are solved syntactically, either by a translator
|
|
or a compiler. If you write just "car", it is expanded to
|
|
"system::core::car" by a translator or compiler, depending
|
|
on what modules you use.
|
|
|
|
* An interpreter (repl) may memorize the "current working module".
|
|
It tells the translator or the compiler what modules should be
|
|
used to identify a variable. So, during interactive sessions,
|
|
a user may feel as if there *is* the current module.
|
|
|
|
* But the fact is, all variables are globally identified at
|
|
syntax level. Therefore, the compiler can identify all
|
|
variables at compile time. This means the following code
|
|
is not allowed:
|
|
|
|
;; I want to access `foo' in the module named some-module-name
|
|
(let ((module (lookup-module some-module-name)))
|
|
(set! (current-module) module)
|
|
(foo x))
|
|
-> ERROR: Unbound variable: current-module
|
|
|
|
(let ((module (lookup-module some-module-name)))
|
|
(module::foo x))
|
|
-> ERROR: There is no variable named "module::foo"
|
|
|
|
Instead, you should write as follows if you need a dynamic access:
|
|
|
|
(let ((module (lookup-module some-module-name)))
|
|
((module-ref module 'foo) x))
|
|
|
|
(let ((module (lookup-module some-module-name)))
|
|
((module 'foo) x)) ;; if module is an applicable smob
|
|
|
|
@end itemize
|
|
|
|
@c $Date: 2002-02-08 10:50:36 $
|
|
@node Findings
|
|
@subsection Findings
|
|
|
|
This section briefly describes module system truths that are one step more
|
|
detailed than "module systems are hairy". These truths are not self-evident;
|
|
we rely on research, active experimentation and lots of discussion. The goal
|
|
of this section is to save ourselves from rehashing that which was hashed
|
|
previously.
|
|
|
|
@itemize @bullet
|
|
|
|
@item Kent Dybvig's module system
|
|
|
|
A paper is available at
|
|
@uref{http://www.cs.indiana.edu/~dyb/papers/popl99.ps.gz,
|
|
http://www.cs.indiana.edu/~dyb/papers/popl99.ps.gz}.
|
|
|
|
This was discussed in 2000-11 and 2000-12.
|
|
|
|
@item Distinction between Top-Level Environment and Module
|
|
|
|
These two are different beasts! Each of the following needs to be
|
|
well-defined with respect to both of these concepts: @code{eval},
|
|
@code{define}, @code{define-public}, @code{define-module}, @code{load},
|
|
working from REPL, top-level @code{begin}, [add here].
|
|
|
|
In guile-1.4, the distinction was not clear.
|
|
|
|
@item Current module system internals
|
|
|
|
@xref{Top,Module Internals,,module-snippets}, for implemetation
|
|
details of the module system up to and including guile-1.6.x.
|
|
|
|
@item [add here]
|
|
|
|
@end itemize
|
|
|
|
@node Selection Criteria
|
|
@subsection Selection Criteria
|
|
|
|
@node Rationale Statements
|
|
@subsection Rationale Statements
|
|
|
|
@node Specification
|
|
@subsection Specification
|
|
|
|
|
|
@c devel/modules/desgin-notes.texi ends here
|