Namespaces (was: Re: [ANN]A plan for 3.8/4.0... (insertdrumroll here))

Andreas Raab andreas.raab at gmx.de
Thu Apr 1 23:23:18 UTC 2004


> > Squeak::Object subclass: #Object
> >     instanceVariableNames: ''
> >     classVariableNames: ''
> >     poolDictionaries: ''
> >     category: 'Tweak-Test'
> >
> > This makes ClassBuilder barf about "Object inheriting from Object"
> > although -by the context provided through the namespace-aware
> > browser- it should be clear that I am in an entirely different
> > namespace where "Object" isn't "Squeak::Object" ("Squeak" is
> > the name of the "root namespace", aka Smalltalk).
>
> I was thinking about going one simpler and having #'Squeak::Object'
> be the key in the Smalltalk dictionary too.

Ah, but that isn't the point here. "Squeak::Object" describes the "global
class Object" whereas #Object describes "class Object in my local
namespace". The trouble is that ClassBuilder isn't aware that #Object has to
be interpreted in the local namespace. The reason why this problem is
interesting is that you may easily expect that someone would want to
"override" the name of an existing class - which indeed is precisely the
point (I wanted to be able to provide a "clean" class hierarchy without
having to resort to prefixing).

> So importing a namespace #Foo
> into a class just means "try prefixing any symbols you can't resolve
> with 'Foo::' and see what happens then".

"Implicit Imports" are VERY problematic in a dynamic system. It raises all
sorts of questions like "what happens if I import A and B and then define
A::Foo and B::Foo" etc. My take on this is basically that really you
shouldn't do "implicit imports" but rather an import is an explicit action
which says importing A::* means (at the point where you "import" via a
dedicated UI action) that you take all of the existing A::* entries and put
their short names into your environment. The "fileOut" version would then
look like:

self import: A::Foo as: #Foo.
self import: A::Bar as: #Bar.
self import: A::Mumble as: #Mumble.

And if you for example add another class to A you would have to manually
import A again - which gives the system the ability to check if there are
any conflicts and ask the user what to do about it (such as renaming).

> And of course a browser on
> namespace #Foo means "show me all the classes with name 'Foo::*',
> and strip off the prefix for my convenience".  They would still
> all show up with their full names in the normal browsers.

That's a horrible idea from the UI point of view. Consider you are looking
at

Foo::Bar>>newArray
    ^Array new: 100.

How could you eventually say what is meant by "Array"? It may have been
defined in Foo, in one of the imports of Foo, in Smalltalk. Pretty much
everywhere. That's why I prefer imports to be explicit - if you see an
unqualified name then the name *does* exist in your namespace or else you
wouldn't see it unqualified.

> Ok, this is another of my PackageInfo-like games that goes for
> simplicity and compatibility over first-class-ness, but it would
> work, no?

Depends on the precise definition of "work" ;-) For me, no, it wouldn't. If
I can't discern what a name I see in some portion of code *means* (e.g.,
where it is defined) I wouldn't say it works for me ;-)

> And would have the short term advantage that code using this
> scheme would still file in just fine to older images, if they had the
> scanner hack.  Although your way is clearly cleaner and more
> consistent when extended to pools and nested namespaces.

Actually there is VERY little work involved in getting the namespace basics
to work. Surprisingly little. The biggest issue is that once you have
namespaces you really want to have tools that are aware of it ... but then
these can be defined in the proper namespace, right? So getting this stuff
into older images (except of course, from interface conflicts) isn't all
that much work.

> > BTW, if you're interested in this I can send you a link to the relevant
> > code.
>
> Please do.

Sent it in another mail already. Oh, and do you realize that the same
"naming scheme" can be applied to selectors? Say having message Foo::bar vs.
Mumble::bar ;-)

Cheers,
  - Andreas




More information about the Squeak-dev mailing list