"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