[Modules] Where do method removals go?

Allen Wirfs-Brock Allen_Wirfs-Brock at Instantiations.com
Wed Aug 22 23:14:13 UTC 2001


IAt 02:16 PM 8/22/2001 -0700, Ned Konz wrote:
>On Wednesday 22 August 2001 01:02 pm, Allen Wirfs-Brock wrote:
>
> > Packages are code modules, they contain class, method, global variable, and
> > initialization definition. They do not have export, imports, or any other
> > sort of explicit dependency specifications. Basically, they just contain
> > code fragments.
>
>Much of the discussion I've read about modules seems to assume that loading a
>module is an exclusively additive process: that we are adding new classes
>and/or methods, or maybe changing existing methods.
>...

I think the best way to respond to this is to more fully explain how Team/V 
works for the benefit of those who aren't familiar with it.

Every higher level Smalltalk language element (classes, methods, pools, 
pool variables, global variables, class variables, initializers, etc. See 
ANSI Smalltalk spec.) have declarative definitions. Packages are containers 
of these definitions. In general, definitions can be arbitrarily 
distributed among packages. In particular, the definitions of the 
components that make up a class can be distributed across packages. This 
allows the definition of packages that extend classes that are defined in 
other packages. As I recall, Team/V didn't extend this to the level of 
individual instance variable definitions, but I would certainly do so today.

Packages strictly partition the image. Every language element in the image, 
must be defined by exactly one (loaded) package. The process of adding an 
externally defined package to an image is called loading. Packages are 
loaded (and unloaded) atomically. You either get everything in the package 
loaded or nothing loaded. When you unload a package everything defined by 
the package is removed.

If you attempt to load a package that defines a language element that is 
already defined by another package in the image, a "conflict" is said to 
exist and the load is aborted. There are various ways to resolve a conflict 
which I'll get to in a moment, but first a little rationale. The motivation 
for this model arose out of the experience of trying to maintain complex 
systems using change sets (file-ins). All too many times, we experience the 
problem where a change set would silently replace a method in another 
"module" then later that module might either be filed-out with an 
inappropriate method definition or other similar problems that I'm sure you 
have all experienced.  You can think about the "conflict" rule like 
this.  Assume that package A defines a method in Object like
         dumbMethod
                 ^"abc"
and that  package B defines in Object a method like
         dumbMethod
                 ^"xyz"
This is a conflict.  Which definition of dumbMethod should the system 
use?  Who can say? Presumably the builder of Package A thought that "^abc" 
was the correction definition and similarly the builder of Package B 
thought ^"xyz" was correct. Arbietrarily choosing either definition is 
likely to introduce a "bug" that breaks code in the other package. So, 
Team/V says, you can have package A loaded or package B loaded but not 
both. However, it does provide tools for a programmer to resolve the conflict.

In this case, the programmer could load Package A, delete dumbMethod from 
package A (implicitly creating a new version of A), and then load Package 
B. Or, the programmer could load Package A, edit the unload Package B (the 
tools support this) to delete the definition of dumbMethod, and then load 
the new version of Package B.  Alternatively, you could just tell the 
package loader to load Package B and delete any conflicting methods.  In 
any case, you have to either created a new version of Package A or a new 
version of Package  B to resolve the conflict.

(Implicit in all this is an important version management concept.  Once a 
version of a module is "published" it must never be modified. It is 
strictly read-only. You can derive a new version from the existing one but 
you can not change the existing version and still retain its version identity.)

Because packages are containers of declarative definitions there is no need 
to allow packages to contain removal definitions.  If you don't want a 
definition, you just don't include it in a package.  In you are creating 
Package C and in the process you decide that Packages B and C no longer 
should contain a definition of dumbMethod, you simply create a new revision 
of A and B without definitions of dumbMethod.

In this scheme there is still a possible role for change sets.  In Team/V, 
the development environment is completely scriptable.  Everything you can 
do in a tool you can also do in a script (the scripting language is 
Smalltalk).  It's quite possible, and occasionally useful, to create a 
script that contains directives, to delete a method from a package, or to 
rename a global variable, or to move a definition from one package to 
another. Such a script is essentially a change set. The important 
distinction is that it isn't a package but rather it is a set of 
instructions for how to edit a package(s) to create a new version of the 
package(s). Whether or nor the edits will produce the intended result is 
dependent upon the version of the package(s) you start with matches the 
assumptions of the person who created the script.

>It seems that this kind of pre/post load code would more properly belong
>in Allen's Clusters. The reason for this is that loading a given module into
>a system with other modules already loaded may require special customization
>for each of the other combinations of modules.

I hope I've provided enough background to make it clear why this is 
unnecessary. If you are loading a package that requires specific versions 
of other packages then you really should be loading a cluster that 
identifies that those specific package versions. In Team/V the "migration" 
from the previously loaded versions of those packages to the required 
versions would be handled automatically based upon the declarative content 
of the packages.









More information about the Squeak-dev mailing list