Namespaces and... modules (was Re: Name spaces in Spoon)

Michael Latta lattam at
Mon May 29 16:32:42 UTC 2006

> Goran wrote:
> - If we go for a runtime messages approach as Dan describes then another
> disadvantage is the analysis of code. Currently I am working on some
> analysis code that is intended to run in the SM server that figures out
> dependencies between packages based on their references and definitions
> of globals. This would not really work if we move this to runtime, or at
> least it gets definitely more complicated.

I would think this would make it easier.  The globals become the modules
themselves and the messages just access classes/globals from those modules.

> I also agree with Michael Rueger (as Dan mentioned) that hierarchies
> *are* complex. Especially considering if we start making remappings like
> the above possible. I urge us all to "remember the Alamo" - 3.3a
> modules. It was too foreign, too "complicated", it made experienced
> Smalltalkers fumble and lose the ball. And the result was that noone
> moved into the "New House Of Modularity" - and thus it died. Please, do
> not underestimate the problems with such "advanced" approaches -
> especially if they radically change the "taste and feel" of Smalltalk.

I agree with this one.  I had not used VisualWorks for many years, and
looking at the current image is quite a shock.  The hierarchical namespaces
and imports is much more complex than required.

> I strongly claim that Namespaces and Modules are two different things -

I strongly agree.  Modules is the ability to package up code/data/objects so
that they can be manipulated as a unit, loaded and unloaded reliably, and
not interfere with the operation of each other.

> So then, if we consider a Module to be a unit of code (let's consider
> only code for the moment - it doesn't hamper the idea AFAICT) then we
> have:

I would rather say as in all of Smalltalk that a module is a set of objects.
Many of the objects in a module will represent executable code.  But, I see
no reason to prevent data objects.  For example if I deploy a module that
includes an LALR parser, I will want to deploy the LALR parse table and
such.  If I deploy a tax module I would want to deploy the tax tables.  One
of the big strengths of Smalltalk is that I do not have to represent
everything in code, I can have objects in the image that support the code,
and I do not need to recreate them each time the "application" starts up.

> 1. References to "globals" that are not in the module itself.
> 2. Defined "globals" in the module.
> [snip]
> I want to make this mechanism visible and much more tangible. I want to
> be able to install a "module" A into the image without having it be
> "activated" (just like Henrik had in 3.3a). Then I can look at it and
> see that yes, it still is not functional because its binding with the
> class Banana is still not fulfilled. Then I can install module B (which
> has Banana) and see that module A is now fulfilled and should work if we
> activate it together with module B.

I like this approach.  The bindings are explicit in each module for all
external reference, and get resolved at load time.  The bindings from the
module get activated separately to allow random module load order.  You
could even have methods on the Module object that perform many operations
like canActivate and exportBindings, etc.

> So to summarize:
> 1. I want to use my Namespaces code, which more or less is "prefixes
> done right". This introduces class Namespace and each prefix corresponds
> to an instance of Namespace held in Smalltalk. Or expressed in
> Smalltalk:
> 	Foo::X == ((Smalltalk at: #Foo) at: #X)
> 	Foo == (Smalltalk at: #Foo)
> 	Foo class == Namespace
> 2. A simple module system would be to create class Module and let each
> instance represent a "piece" of the image with inputs and outputs like
> above. It could have behaviors like activate, deactivate, hasAllInputs,
> inputs, outputs and so on. How a Module defines its boundaries can be
> discussed - perhaps it has a list of PIs, or whatever. And again, it can
> have a few different implementations depending on if it is just a chunk
> of object memory with named inputs/outputs or if we actually know it is
> code.

So in your system we can have a single module contributing to multiple
namespaces, and namespaces that span modules.  That seems appropriate, the
tricky part will be that both modules will need to ensure that the Namespace
object exists but neither can own it.  So the load process of a module can
create an object that is outside the module.

Ideally each module could be an image segment and loaded as a block with one
memory mapped I/O.  That may be a bit ambitious in the first phase, but
seems a desirable end goal.

It might be simpler to just have Module == Namespace.  While I can see the
value in the two part approach it also adds complications of its own that
will be rarely used.  I think it far more likely that a module will want to
attach a method to a class owned by another module, and that is not
addressed in this proposal as it is not just a name binding issue.  To do
that properly there needs to be a "partial" class in the module that is
merged into the real class at load time, and can be unloaded as well, or
each Class must have an "extensions" collection that holds all such
"partial" classes and are treated as extensions.  While more flexible and
cleaner this too is fairly complex and not to be taken on until a proven
need is seen.  I would go with inserting the methods on load into the
existing class, but having a "partial" class object in the module that is
responsible for the load/unload process.

> I am not sure if I made the above easily understandable nor if it is a
> good way to do it. But IMHO it seems simple, *understandable* and rather
> generic. It is all about hooking a piece of object memory into the image
> and make sure it can reconnect its connections in both directions
> (inputs and outputs) using name lookup.
> regards, Göran

Michael Latta

More information about the Squeak-dev mailing list