A lightweight namespace "proposal"

Peter van Rooijen peter at vanrooijen.com
Wed Apr 21 23:52:36 UTC 2004


Hi Goran and all!

I have been lightly monitoring the namespace discussion and I believe 
that with Goran's latest proposal we are reaching the stage where 
something is going to happen. I applaud you!

I have noticed that the fundamental question has been asked: "which 
problems are namespaces supoposed to solve?". I haven't seen it answered.

The second fundamental question is: "what is a namespace".

Here are some answers that may help the thinking and if you like them, 
will help answer other, related, questions, too.


"Namespaces are clearly the answer, but what is the problem?"

The problem is that it happens that a programmer wants to use a name, 
but the name is already taken in the one global namespace that we 
currently have.

The 'best' workaround/kludge is to use class name prefixes. So, if one 
makes a class that implements the abstract data type "set", one might 
call it SmSet.

Bad aspects of this:
1) We now have to write SmSet each time instead of simply Set
2) Only a human understands that Sm is the prefix and Set the short 
('real') name.

If we make the distinction between the prefix and the short name 
explicit, we can solve this:

Say we use the notation Sm::Set, and then we have the ability to use Set 
to mean Sm::Set in code that is in the Sm namespace (I'm not yet saying 
what code exactly is - e.g., are class definitions also code? - and I'm 
not saying how code gets to be in a namespace; this will be addressed 
below). Bad aspects of traditional prefixing are now solved, hurray!

[A worse workaround is to call the class TreeSet or something else which 
is globally unique, just because that is globally unique, but this is 
not really a solution, I would never advocate that, and hope it doesn't 
require further argumentation to reject.]

So the short answer to "which problem do namespaces solve", is "class 
name prefixes".


"What is a namespace?"

The answer basically follows from the above: "a namespace is a place for 
  classes with unique short names. Every class exists in such a place.".

Therefore, placing classes in the same namespace means accepting the 
responsibility to give them unique names for that namespace. Nothing 
more, nothing less.


So, now the two main questions have been answered, and we can look at 
the related/derived questions:

Some related questions:

1) How to treat the already unique set of class names in the images as 
they are, without namespaces?
2) What is the relationship to packages?
3) What kind of resolution mechanism/rule is needed (if any)?
4) Should namespaces be reified?
5) Is there a root namespace, and if so, how should we refer to it?
6) Is there some kind of shadowing going on?
7) How will this work with old/new code and forward/backward compatibility?
8) Should code in a namespace only recognize/resolve short class names 
in its own namespace and the root namespace, or optionally others as 
well (suggesting reification and an import mechanism).
9) Are multi-level namespace names allowed (Sm::Public::Set)?
10) How should class references be compiled?
11) How does code get to be 'in a namespace'?
12) How to guarantee uniqueness of namespace names?
13) What is the relationship with class and pool variables?

Some answers (or statements/observations suggesting answers):

The classes that are now already in the base image, can (and should, in 
my opinion) all go in the same namespace. No Collection::Set, 
Magnitude::Float or Network::Socket (these are examples of 
namespace/package confusion).

I would advocate keeping it all very simple by making the root namespace 
have *no name*. This makes the root namespace unique syntactically and 
avoids all discussion about naming it Smalltalk, Squeak, Root, or whatever.

So you write Set to refer to whatever Set is seen/visible from where 
(i.e., in which namespace) the code is, and if you absolutely want the 
one in the root namespace, you write ::Set. This suggests that if you 
write Set and you are in the namespace SqueakMap, you will get 
SqueakMap::Set if it exists, so it suggests the possibility of 
shadowing, which I in fact advocate.

Of course if you write Set and your code is in the root namespace, it 
can only refer to ::Set. Very nice for existing code in the distribution 
images, it is not affected at all :-).

It would be simplest, and work just fine, to have only one level of 
namespaces, and all code sees only the short class names in itself and 
the root namespace. Multilevel namespaces, imports (explicit and/or 
implicit), it can all be added later if and when it is deemed useful, 
after some significant experience with a two-level system has been gained.

Code gets to be in a namespace by virtue of a declaration. If it is 
without a namespace declaration, it is in the root namespace. If a class 
has a namespace declaration in its definition, all its methods are in 
that namespace. If a class has no namespace declaration, but its package 
has one, the namespace of the methods of the class are the namespace of 
the package. The namespace of a package is also used for resolution of 
class and pool names in all class definitions in that package.

Namespace name uniqueness is handled by a social mechanism. Since 
namespaces in this lightweight namespaces proposal aren't defined by 
themselves, but are implicit in class and package definitions, 
declarations of namespaces with the same name refer to the same 
namespace, and you can't have duplicate short class names in the same 
namespace. If there is no conflict in short names, two authors can 
accidentally choose the same namespace name and the code will load 
together and even work!

Class variables and imported (in the class definition) pool variables 
still resolve before (and thus shadow) the other names. Namespaced names 
(from the root namespace or the non-root namespaces) are a replacement 
for the single global namespace of classic Smalltalk.


Finally:

I really believe that it can be this simple, and that this is really 
useful, in this simplicity. Not having implemented it, I hope I didn't 
miss something that makes this proposal not work :-). I will be happy to 
try and respond to criticisms, and just as happy to clarify what isn't 
clear if someone should be interested in clarification.

Cheers,

Peter



More information about the Squeak-dev mailing list