[Modules] A proposal for Modules, Packages and Dependencies

Henrik Gedenryd Henrik.Gedenryd at lucs.lu.se
Thu Aug 23 15:57:23 UTC 2001


Les Tyrrell wrote:

> I would like to throw in a few words of caution regarding a few things.

When I saw these critical points, it didn't take long before I came to see
this asa positive thing. This is exactly how open source is supposed to
work: Put out a small proposal early and let everyone in on its refinement.
It also seems that with this we have managed to focus our discussion around
something concrete, so that we can make some actual progress.

Thankfully, others have already answered some concerns already!

> I feel very strongly that anything we do to change Smalltalk should be done
> in the spirit of [Smalltalk]

I perfectly agree. There is one but: we shouldn't preserve the weaknesses.
ST has been weak wrt modularity, and the solution is not therefore to have a
weak modularity scheme.

> Thus, I have strong reservations regarding any scheme in which modules are
> given explicit information about other modules.  This includes such notions
> as "pre-requisites", or modules "containing" other modules.

My preference is not to lock the user into one way of doing things, or even
two, but preferrably a dimension, so that you can choose what suits you, but
even more, to move along the dimension as a project progresses.

My scheme allows two forms of external references: explicit and implicit
ones (Module Name vs. just Name being available via import). The latter form
precisely does allow 'lax' specification of dependencies. My previous
example of a 'Root' module, where all names are available (as a solution to
Dan's  point about 'allowing simple hacking') represents the extreme end of
lax-ness if you work there, or make your module "import the Root".

But note that such lax-ness is the opposite of modularized code, which is
the very thing we aim for here!

To increase rigor (and introduce modularity), you would convert your lax,
implicit refs in code be explicit, and the "uses"/imports more specific
about what other pieces of the system puzzle your code depends on. This is
how you make code modular, by minimizing interdependencies.

In fact, this is how I envision that we would turn the present image to a
modularized one. Lots of code must be changed! There are almost 800
references to Smalltalk alone, where it plays a number of roles: globals
dictionary, vm proxy, etc. This can't happen any other way than gradually.

> modules "containing" other modules

This is simply the single means for organizing the system. A flat space is
what we have today and what we are working to get away from. A module system
that isn't hierarchical defies its own purpose. It would just take us from a
flat name space to a flat module space, and that ain't very far. It would
make the system "segmented" but not structured. And like above, if you don't
want to structure your own work, then you can still just not do that.

For example, the hierarchy allows all Squeak uses to share a single module
naming scheme, the "virtual module hierarchy". It also allows one to
structure an implementation into parts that are hidden from the outside.

> which must be explicitly named.

This is a point where I waffled and where I am grateful for the feedback
that brought this out. In my effort to keep it as simple as possible, I went
a bit too far in playing down the part about module parameters (even though
the idea is there) and I plainly forgot to work out that aspect.

Consider the analogy between my module format and methods, i.e. module
parameters/imports are like method arguments. In particular this means that
you should be able to specify the parameters from the outside (but with an
option to provide defaults), when you "instantiate" a module.

Ie. if ModuleX accesses the Transcript, but should allow multiple
implementations, it will take the TranscriptModule as a parameter that you
provide when ModuleX is included in a system. E.g. when SystemY has ModuleX
as part of it, its build schema says something like

    SystemY submodule: (ModuleX transcriptor: GuiTranscriptModule)

whereas a headless system might say:

    MyServer submodule: (ModuleX transcriptor: StdoutTranscriptModule)

modulo the specific details. So I was unclear on that imports/parameters
should always be specifiable from the outside; this adds some extras to the
specification.

I hope the analogy with method parameters is clear enough to explain how it
would work. If not, let me know.

> specifying dependecies at module load time

In 99% of all cases this is a good thing. You typically want to be able to
ensure consistent loading before you start the loaded system, without having
dependecy problems show up until you run the program. I'd say most of the
time. How often will someone want to build a system whose module composition
is unknown until, and/or may change during, the execution of the system?

And the flexibility of the scheme allows late-bound dependencies in the
100th case, e.g even by putting intelligence under the ModuleX method in the
access message SystemY ModuleX.

> self uses: #(SqueakTranscriptModule) "I don't really understand
> the syntax, it doesn't matter"

These are messages sent to the module, as part of a "script" that a module
runs to build itself; this is just the simplest solution. 'self' was to keep
the definition relative, as I noted it was just one option I chose.
#(SqueakTranscriptModule) is just the Smalltalk equivalent of
Java.blah.math, as #(Java blah math). An array of symbols is used so that
you can load this code without having already defined that name.

> two orthogonal artifacts: packages and clusters.

I saw that in ModSqueak as well. I have already detailed my solution, which
allows modules to both specify their composition (like clusters) and their
contents (like packages). This is  that handles one each.

By analogy you could divide methods/functions into code packages that hold
statements and variables only, and function clusters which contain
parameters and refs to other {function clusters OR code packages}.

I see two advantages in this: you have one instead of two different concepts
(three if you count the base class as in ModSqueak), both in the formal
model and to keep in your head, and you also use familiarity and reduce the
conceptual complexity by making a close analogy with methods (which take
parameters that you provide when you "instantiate" the method).

I also hope it is clear that there is no lack of power in this scheme.



That's it, let me know if I haven't answered something. I'm also willing to
produce a revised specification when the time is right.

Henrik






More information about the Squeak-dev mailing list