A little namespace "proposal"

Roel Wuyts Roel.Wuyts at ulb.ac.be
Tue Apr 6 15:18:44 UTC 2004


Hi Goran,

Just wanting to make sure I got what you were trying to do, so I could 
give constructive comments instead of wandering of into some unintended 
direction :-)

So, executive summary of the problem: to have less chance of having 
name conflicts between classes in different packages (your point 1). 
The other points seem to be more future-directed (I mean, not adressing 
a direct goal, but interesting things we could add later).

I agree to the goals you set out (except for the "optimistic", since I 
don't think I get the real point, but ok). Indeed, if you want to add a 
backwards copatible, non-obtrusive, easy-to-use mechanism then these 
are the goals you want.

Now about the model itself (hehe, I bet that you are sitting on the 
edge of your seat, Goran :-) ): I like it. I think it tackles your 
problem. I put some comments in your original proposal below.

> It goes something like this:
>
> - Instead of having one big bag of globals (Smalltalk) we have a a
> number of Namespaces. A Namespace is just a Dictionary of associatons
> between names and objects like Smalltalk, and the Namespaces aren't
> related to each other in any way - we just have a flat list of them. So
> typically we have say these Namespaces (which I will use in the rest of
> the post as examples) and many more:
>
> 	Kernel
> 	Collections
> 	SqueakMap
> 	Seaside
>
> (note how I have made this a bit coarser than the categories - of 
> course
> the actual partitioning is open for discussion, but just bear with me
> for this post)

Ok, few coarse groups. Got it.

>
> - When creating a class in a class category the template would look
> like:
>
> 	Object subclass: #NameOfSubclass
> 		instanceVariableNames: ''
> 		classVariableNames: ''
> 		poolDictionaries: ''
> 		category: 'Kernel-Processes'
> 		namespace: 'Kernel'
>
> ...thus autopicking the PI-first part of the category, or perhaps like
> this:
>
> 	Object subclass: #Kernel::NameOfSubclass
> 		instanceVariableNames: ''
> 		classVariableNames: ''
> 		poolDictionaries: ''
> 		category: 'Kernel-Processes'
>
> ...whichever we like the best.

No preference, don't care.

>
> - There is no explicit "creation step" for a namespace (or removal) -
> they are simply created and removed "on demand" or whatever. This means
> we all can "carry on just like before". :) Or in other words, it is an
> attribute of the class.

Yes, I think I like it. But it is very dubious: it means that it is 
easy to make stupid spelling mistakes when creating the class, 
resulting in a namespace being created without me knowing it (see 
further).

>
> - When writing code you can refer to the class Delay in two ways -
> "Delay" or "Kernel::Delay":
>
> 1. If you type in "Delay" then we first look in the local Namespace of
> the class you are editing. If there is a "Delay" in that namespace then
> we bind to that. If not, then we look in ALL other Namespaces and if it
> resolves in none we signal an Exception. If it resolves to one we ask
> the user to confirm the right binding. The source will still read
> "Delay" but the binding is still in itself fully qualified as
> "Kernel::Delay" since it is in fact an object reference to that class.
> If it resolves to more than one, the user gets to choose which one and
> it will be expanded to "Kernel::Delay" in the source (if that is the 
> one
> he/she chooses).

I would never want to see Delay, and always Kernel::Delay. In your 
proposal, things get ambiguous if one adds another namespace that 
introduces Delay later on. To make sure I am clear, I'll give a little 
scenario:
(1) I add a class Roel::Classification, so a namespace Roel exists, and 
my class in it.
(2) I add a class Roel::Item, that has a method foo that somewhere 
says: 'Classification new'.
	We all know what this means: a Roel::Classification new. So in your 
proposal, the source reads as above, in mine it would read 
'Roel::Classification new'.
	No problems yet.
(3) I load another package that has a class Alex::Classification (or I 
add it myself, doesn't matter).
(4) I open a browser on my class Roel::Item, and have a look at the 
source code. Now it is not so clear anymore which classification is 
meant without the prefix.

So I am afraid that omitting the namespace is not a good thing with 
respect to evolution and change. Adding the prefix makes it sound 
again. And because needs to do the same checks, it does not even change 
anything for the developer.

Note that this also means that it is more likely to notice spelling 
mistakes with namespaces, since you've much more chance to see them. 
When the lookup finds them in the misnamed namespace, you probably 
won't see a mistake until much later, which can be quite annoying.

>
> Note to Andreas: The signals and code here is of course up for
> discussion, I really don't care as long as the end result is the same.
> :)
>
> 2. If you type in an explicit reference "Kernel::Delay" then the
> Compiler (or whatever) first checks for the Namespace "Kernel" and if
> that exists looks for the name "Delay" in it. If it isn't resolved then
> an Exception is signaled and the Browser should look through all other
> Namespaces for "Delay" and if found - ask if it should be corrected. If
> there is only one Delay in the system to find, then it can be corrected
> to "Delay", otherwise it will be corrected to the fully qualified form.
>
> The net effect of the above is that Squeak code as it stands today 
> still
> works fine after a recompile. I think. :).

Yes, I also think. Even in "my version".

> Note also how this eliminates
> the needs for imports, the short form is usable in two scenarios:
> 	1. The name referenced is in the local namespace.
> 	2. There is only one such name in all the other Namespaces.
>
> This will also encourage us to to still have globally unique names in
> our packages which is a GOOD thing because no matter how cool 
> namespaces
> we have - it all ends up in our heads - and our heads is just one big
> namespace. If many namespaces have "Delay" entries, it will still mess
> with our heads. See below for a little "feature" that still makes it
> possible to have duplicate names without "disturbing others".
>
>
> - When a new class "SqueakMap::Delay" is created the tools should warn
> me that there already is a class called that in another Namespace and
> that it is generally better if the classes don't conflict by name
> because of the way resolving works. Sure, currently (before we get a
> superserver somewhere that can do lookups globally) this only checks
> against my current image but should still be useful.
>
> I then have a choice:
> 	1. Keep the name Delay and thus causing people with my code and the
> Kernel code in their image to be forced to choose which Delay they mean
> every time they only write "Delay" instead of a fully qualified name.
> 	2. Rename it to MapUpdateDelay and be fine, that might very well be a
> more precise name.
> 	3. Keep the name Delay but mark the name in the namespace as "shy". 
> All
> names in all namespaces are by default used when trying to resolve a
> non-qualified name (as the resolving algorithm above showed - this is 
> at
> the heart of the "optimism") and marking it as "shy" merely means that
> when someone writes "Delay" the entry "SqueakMap::Delay" will not be
> presented as a choice. It doesn't mean anything else - for example,
> typing "SqueakMap::Delay" works just fine regardless if it is "shy" or
> not.

No, I don't like the last option at all. 1 and 2 leave the 
responsibility in hands of the developer, which I like for handling 
this kind of conflict. Option 3 is more complicated, you'll have 
kind-of invisible stuff going on, you need to declare the shy-ness when 
you add the class (since you don't create namespaces explicitly), etc.

>
>
> - The Dan-test, what happens when we install/uninstall a package of
> code? Well, I am completely disregarding stuff that Monticello already
> solves/tries to solve. So let us only look at what we do with our
> Namespaces.
>
> Since the fact of which namespace a class resides in is an attribute of
> the class itself it means that new code filed in can:
> 	1. Introduce new Namespaces
> 	2. Add entries to existing Namespaces
> 	3. Overwrite entries already in existing Namespaces
>
> If we only would allow the first 2 then all would be trivially simple.
> :) Since all existing references in the image (see above) are fully
> qualified then new entries or namespaces can't affect anything.
>
> What happens with the overwrites? Well - I am not sure - Avi can 
> perhaps
> help out in this area. One idea is to add a mapping mechanism to the
> filein code. Trying to file in an overwrite will simply signal an
> Exception and the user will have to add a mapping perhaps just putting
> it in another Namespace to at least get the stuff in.


On 06 Apr 2004, at 16:17, goran.krampe at bluefish.se wrote:

> Hi Roel!
>
> Roel Wuyts <Roel.Wuyts at ulb.ac.be> wrote:
>> One simple question I had when reading the proposal (and before really
>> giving comments):
>>
>> What exact problem do you want your namespaces to solve (I am not
>> talking about the primary values of your solution)?
>> Is it name clashes?
>>
>> (several people here want to solve different things with the
>> "namespaces" - from simple naming conflicts to different scope lookup
>> mechanisms to more packaging-issues to deployment to .... So I'd like
>> to be sure :-) )
>
> Hehe, such a question bodes not well. :) Andreas has a very immediate
> need in his projects (not sure exactly what it is though) and I am more
> thinking about making Squeak a better place for our circa 400 (and
> growing) packages on SM etc.
>
> So I am probably trying mostly to:
>
> 1. Make packages less likely to conflict. This means that yes, it gives
> a package a way to have named objects (classes) in its own little space
> and be sure that those names are "ok" - meaning that future other
> packages will not stomp all over them. I didn't write about that - but
> to make this "fool proof" we would need to register unique Namespace
> names in say SM. Much like the PIs are today. Hey, perhaps they are
> simply the same? :)
>
> 2. Not any real difference in how "scope lookup mechanisms" I think.
> Well, the qualified syntax is introduced and the Namespace object
> probably too - meaning that we have two new "tools" we can think about
> and use. For example, it wouldn't be too far off to think about 
> swapping
> one Namespace for another. Given Namespaces we could in theory load two
> Socket packages into the image at the same time - one in "Sockets" and
> another in "CoolSockets". So CoolSockets::Socket and Sockets::Socket 
> are
> available at the same time. I could one or the other by direct
> qualification, but I could also perhaps swap these Namespaces. Or at
> least map "Sockets" onto "CoolSockets". Food for thought.
>
> 2. Packaging and deployment. Well, the only thing I can think of "off
> the top of my head" is that a package which only has classes (or other
> objects) in its own Namespace, would always be installable into an
> image. Either in its own Namespace or - in a worst case scenario - in
> another Namespace given by the user. The simple fact that we at least
> *have* multiple places where we can put the classes makes it quite
> simpler, no?
>
> Not sure if this made you any wiser. :)
>
> Please remember that my proposal is just a little, simple, humble
> proposal. It is not a fancy cool Classbox or anything like that. But it
> seems to me it could go a long way nevertheless, and perhaps it is so
> simple that we could actually introduce it without people screaming
> bloody murder. :)
>
> Note that it would:
> - Not introduce any new steps when programming. No "first create your
> namespace" or "first add an import".
> - All old code would still look and work the same. (I think)
> - Only introduce a rather simple addition to the class template that 
> can
> be default-filled rather easily.
> - Add a new syntax for qualification (the "::") that Squeakers don't
> even need to write - it will be auto corrected for them. :)
>
> In short - I am proposing to chop up the Smalltalk Dictionary into a
> Dictionary of Dictionaries. :)
> But coupled with a few tricks that I described it feels like it could
> work pretty good.
>
> regards, Göran
>
>
Roel Wuyts                                                              
   DeComp
roel.wuyts at ulb.ac.be                               Université Libre de 
Bruxelles
http://homepages.ulb.ac.be/~rowuyts/                                    
Belgique
Board Member of the European Smalltalk User Group: www.esug.org




More information about the Squeak-dev mailing list