"Robert Feldt" <feldt / ce.chalmers.se> wrote in message news:Pine.GSO.4.21.0110232319250.23977-100000 / ros.ce.chalmers.se... > On Wed, 24 Oct 2001, Rich Kilmer wrote: > > > Question: Don't modules give you a namespace capability? > > > Not in the sense below. > > > I realize it does not in the sense that overriding a method on class > > Array will effect the entire interpreter, but in the sense that it > > partitions symbols (variables, classes, modules, etc). > > > > Are you speeking here of an ability to actually change Array, but have > > that change only be available to the originating "namespace" and classes > > (or modules) defined within a "namespace" are only visible to that > > "namespace"? > > > Yes, its a "namespace" in a different sense. From my understanding > Smallscript/AOS and recent Smalltalks have this latter thing. And it > seemed to have evolved because people were having problems with this. But > I'm not sure of this. > > A sort-of scaled up Ruby/Behaviors la David Black?! ----------------- From Dave Simmons ----------------- Background: The namespace concepts being discussed here regarding Smalltalk were principally my work over the last ten years or so with QKS Smalltalk and subsequently with the SmallScript language. Modules and Namespaces are different concepts that often overlap because both are units of organization. In many languages these concepts are not distinguished and that ultimately leads to problems and unnecessary complexity. --- A module is a unit of deployment and packaging (distribution units). They may also be thought of as a unit of "ownership". A namespace is a unit of lexical binding/scoping. They should also be thought of as a unit of "priviledge/permission". A module may contain code that extends or changes the contents of one or more namespaces. Two or more modules may extend or change the contents of the same namespace within a given program. Modules may reference or depend on other modules and have a variety of prequisite/versioning issues. Modules are best thought of as generic self describing/reflective repositories of "things" which include code. Modules may be combined into a deployment unit that in Microsoft.NET terms is called an assembly, but which I have generally viewed (prior to .NET) as a rich COFF/ELF/PE/etc file. Similar to the form a Macintosh executable takes with its resource fork. It may help to think of modules as being a first-class language manifestation of projects within a classic IDE. ----- I can illustrate the problem being solved as follows: a) Assume person A has writen some class Foo. (It might help to think of person A as the language vendor/provider/implementor). b) Person B decides they want to use class Foo in their project. c) Person C comes along an really likes Foo and wants to add some new features to it rather than subclassing it. Why? Because from an OO design viewpoint it makes more sense to extend the classes behavior than to rewrite the module that class Foo came in. Also, looking to worlds like Microsoft.NET, they may not have the source to assembly/module to make such changes. d) Person B also recognizes that it would be useful to extend Foo and make a number of modifications. ----- At this point we have a lot of potential problems that using "selector/message-namespaces" [which I invented for dynamic languages] will readily and safely solve. Here are just a few of the obvious problems that are possible: 1) Person A adds new behavior to Foo which conflicts with work done by person B or person C. 2) Person C decides they want to use person B's code within their program, but the changes/extensions to Foo conflict. Or vice versa for person B using person C's code. ----- What we would like is a way to dynamically add "partitioned" behavior (methods) to classes (or individual objects) that already exist and are defined by someone else. I.e., You gave me a "Foo", we all agree it is the same class. But, I would like to have Foo objects within my project/code do things differently than they might in your code. And, I want my code and your code to be able to coexist in the same running program/scriptlet/applet. So the example posted a few messages back where an inner-class was created that "refined" a more general class will not work. We need the behavior to be partitioned safely, and we need it work on all instances of the original class. ----- To solve our problem with modules and namespaces: 1) Person A defines moduleA which acts as both a class and namespace. They then create class Foo inside it. 2) Person B defines moduleB which acts as both a class and a namespace. They then create their modifications packaging them in moduleB and scoping their Foo changes to moduleB. 3) Person C defines moduleC which acts as both a class and a namespace. They then create their modifications packaging them in moduleC and scoping their Foo changes to moduleC. At this point everybodies work is segregated but also has the virtue they can all be loaded at the same time within the same program. ModuleB will depend on ModuleA. ModuleC will depend on ModuleA. When moduleB loads it will augment Foo. But since all the modifications are "scoped" to moduleB they will not be visible to any code which does not have access to moduleB as a namespace. When moduleC loads it will augment Foo. But since all the modifications are "scoped" to moduleC they will not be visible to any code which does not have access to moduleC as a namespace. So for code which does not have access to moduleB or moduleC, but which does have access to moduleA the Foo class will look and behave as person A intended. For code that has access to moduleB the changes in moduleB will all be accessible and will take affect accordingly. For code that has access to moduleC the changes in moduleC will all be accessible and will take affect accordingly. For code that has access to both moduleB and moduleC, the order of importing will determine which module's changes take precedence over the other. However, the general component design scenario is that the changes made to Foo will be private to the implementation of componentized/modularized services that moduleB exposes. Module name: A { Class name: Foo. } ---- Module name: B imports: A default-scope: B { Class ref-name: Foo { Method [ myPrivateX ... ] } Function [ someCode(aFoo) aFoo.myPrivateX /* invokes the #B.myPrivateX version */ ] } ---- Module name: C imports: A default-scope: C { Class ref-name: Foo { Method [ myPrivateX ... ] } Function [ someCode(aFoo) aFoo.myPrivateX /* invokes the #C.myPrivateX version */ ] } P.S., all the braces "{" and module declarations are actually optional if these modules were defined in separate files. I just added them for clarity in writing the code here. I.e., "" Person C could have written their code as Module name: C imports: A. Method class: Foo scope: C [myPrivateX ...]. Function [someCode(aFoo) aFoo.myPrivateX ...]. -- Dave S. [www.smallscript.org] > > Regards, > > Robert