A little namespace "proposal"

goran.krampe at bluefish.se goran.krampe at bluefish.se
Sat Apr 10 16:43:41 UTC 2004


Hi Lex and all!

"Lex Spoon" <lex at cc.gatech.edu> wrote:
> goran.krampe at bluefish.se wrote:
> > If the code read "Delay" I have no idea which class this is bound to
> > *unless I look at the imports*.
> > So the import list for the class will have to be visible somewhere,
> > right?
> 
> Yes, and this seems good to me.
> 
> If you see Delay in some code then you are very likely to know which one
> is being spoken about in the code.  You usually know whether you are
> reading Squeak code or Tweak code.

Yes, and this is just as in my proposal - if the reference is in the
local namespace then it is rendered unqualified.

>  And in the less frequent case that
> you are not sure, you can either look at the import list, or you can
> click on the variable and do "explain".
> 
> This is an issue we already have and that will not go away under any
> reasonable proposal I've seen, including the "quick proposal" baseline. 
> If you see Delay in the quick proposal baseline, you still do not know
> if it is a class variable or an instance variable or even a temporary
> variable.  To know for sure you must either examine the class definition
> carefully, or you must use the "explain" menu item.

Well, I think you are pushing it a bit. Temp vars are quite easily
discovered by simply looking at the declaration at the top of the
method. Normally, a name starting with lower case which is NOT a temp is
typically an instvar. If it starts in upper case then sure, it can be a
class var or a global - so if you hesitate regarding that distinction,
you need to check the class definition. Typically you don't recognize
the name as a class and then you check if it is indeed a class var.

But if we have imports and multiple namespaces (with overlapping names)
then an import-model will create situations where the reader *thinks*
he/she knows what the code is:

"d := Delay forSeconds: 2."

If I read the above I have today no *reason* to look at the class
definition, because I am pretty sure it must be the standard class Delay
that is referred to OR the author is tripping me up badly if he has a
class var named "Delay", but I am simply assuming he isn't doing that.

IMHO it is bad enough that we have the current potential shadowing going
on with classvars - your proposal with "Java style" class level imports
will increase this problem even more, because depending on the import
list in the class above "Delay" can be different things.

In my proposal (given the default LookupContext), if it looks like
above, it can only refer to Kernel::Delay. (Unless there is no Kernel::
namespace in the image of course)

> I find this situation just fine.  It's lexical scoping at work.  When I
> browse a class, I accept that I need to know the lookup context of the
> code.  When I browse my own code I will know what the context is, and
> when I browse someone else's code, I can easily check what the context
> is.
> 
> I don't like the idea of fully qualifying stuff all over the place just
> in case some user gets confused.  It's a pessimistic stance that harms
> more often than it helps.  I would much rather leave the default
> presentation up to the author.  Lexical binding means that the tools can

This last paragraph makes me think you are missing some crucial points
in my proposal.
I repeat - you will not need to fully qualify when entering code nor
when browsing most of the code.

> always expand and show more information whenever the user desires;
> showing less information--i.e., more focussed information--requires an
> author's touch.

I don't buy this as some kind of natural rule (requires).

My proposal may not be "just as in every other language", but that is
IMHO its strength.
It is simpler and keeps the "feel" of Squeak as before. Going for a
"Just like in Java class level import"-model seems to me to be a really
effective way of destroying a good part of the simplicity that Squeak
and Smalltalk has.

> Let me give an analogy from another place in computerdom where I have
> practical experience: indentation in text editors.  Many text editors
> can automatically indent C code, but doing it properly requires the
> editor to know what style of indentation is being used in the particular
> file.  The way it's done in Unixdom most of the time, however, the C
> files do not themselves contain an indication of the style used. 
> (Sometimes, but not usually).  Thus, I must manually configure my editor
> before I can edit the code in these files.  It's a major pain.
> 
> The tools-only approach to namespace imports is actually worse than
> this.  While I must set up my C indentation to *edit* other people's
> code, we are talking about setting up a LookupContext before I can even
> *browse* other people's code.  That seems like a major pain and a big
> step backwards over the simplicity of browsing Smalltalk right now.

I have no idea what you are talking about here. Why would you not be
able to browse other people's code? Why would you need to "setup a
LookupContext" at all?

I have explained that my proposed standard implementation of a
LookupContext (for the normal Squeak env) does not carry any state and
would simply render and accept entry of unqualified names when either:

1. There is only one such name in all loaded Namespaces.
2. The name is defined in the Namespace of the class itself.

Given the above two rules you could take the current Squeak with
probably all packages currently on SM and just browse away to your
heart's content. Everything will look the same as before! Why? Simply
because 99% of all our current code *has unique class names*.

Sidenote: It is *Andreas* that is thinking about having "import lists"
in *his* LookupContext implementation.

> Overall, tools-only lookup contexts look like a fine way to start, but
> let's go ahead and start thinking ahead to where we want to get, lest we
> code ourselves into a corner.  The namespace listings need to be in the
> code *somewhere* or we are going to add a lot of nuisance to people
> browsing code.  Classes seem like a reasonable place to put them, but

I still can't understand the "lot of nuisance" you are talking about.

> make packages would be an even better place.  And most likely, we will
> want to have the option of putting  import lists in different places,
> everywhere from method to class to package.

I definitely don't agree. :) I am striving for a simple model. I don't
want any import lists.
You want to have them in even *multiple* places? Don't include me in
your "we" please.
 
> > And another problem is that the compilation of a method now depends on
> > the import list. 
> 
> This is true whether the import list is in the tools or in the code.

No. Again it seems you haven't understood my proposal. The source
*always* has qualified names so *there are no imports* and the code
*compiles just like today*.

In fact - my experimental code still has ALL globals in Smalltalk, they
just are named "Kernel::Delay" instead of "Delay" and they are ALSO kept
in the Namespace objects (redundant - yes, but it has a bunch of
advantages).

Let me pick another nice example where the use of import lists will
complicate things - "do its". People who have used VAJ (probably the
same in Eclipse) remember that the Scrapbook (=workspace) first needs to
be told in which class it runs!

So what happens with do-its in my proposal? Nothing dramatic whatsoever!

"(Delay forSeconds: 2) wait"

...will work just fine *as long as there is just one "Delay" in the
image*. If there are more than one you will have to qualify, but we all
realize this will be quite seldom. (and given the addition of "shyness"
that I still think is important the situations will be minimized even
more).

What happens in a "Java style class level imports"-image? I honestly
don't know. Lex? Will I be forced to type "Kernel::Delay"? Or will I be
forced to first explain what Namespaces I am importing for this
particular workspace etc?

> > In short - it just feels like a "per class import"-list doesn't fit
> > well, it seems to me that there are multiple scenarios where it gets
> > complicated.
> 
> I don't see an extra complexity anywhere.  Your main argument seems to
> be that it can confuse users to use someone else's lookup context.

You don't see extra complexity anywhere? Well, let's see - a few comes
to mind:

1. We need to add "import lists" to class definitions. And when the list
is changed we need to recompile all methods of the class. This can also
be triggered by editing a method, if the tools should "auto modify the
list" for us, not sure what that might lead to.

2. We need to figure out how to deal with doits, workspaces etc. How?

3. Two identical methods in two different classes will potentially be
different.

etcetc

Also - I have no idea what you are saying my "main argument" is.

[SNIP]
> > I agree with this, we can add smarts. I still don't agree with adding a
> > per class import list.
> > Not sure what you meant with "alias" though.
> 
> I meant aliases for namespaces themselves, not for elements of
> namespaces.  But it points to bigger issue.
> 
> The specific issue is that if there are two implementations of URL's,
> I'd like to be able to have a NewURL namespace and an OldURL namespace,
> plus a URL namespaces that is an alias for one of these two.  Then I can
> swap implementations by swapping the alias.

Not sure we really need to add an extra mechanism (alias) for this. You
can still easily implement tool support that remaps the references -
since we are talking about compile time stuff you will still need to
recompile anyway.

> That's not the most important thing.  More generally, I'd like namespace
> issues to remain maintainable by users, even if tools fill them in
> automatically to begin with.  I'd like to be able to write a class that
> imports NewURL, and then switch it to OldURL.  Or, I'd like to be able
> to prefix a class with an import of NewURL, which overrides the URL
> classes that are in Squeak.

Personally I can't see why these things can't be done without an import
list model. In fact - it seems simpler to implement it without lists,
because in my model all references are qualified and thus easy to find
and rewrite. :)
 
> Also, it seems useful to have some large generic aliases like
> NetworkingStuff and Morphic and Squeak and Tweak that people can import,
> so that they do not have to import loads of individual namespaces to get
> anything done.  Thus, it seems good to add in some inheritance between
> namespaces at some point.

And finally I think the above really shows that your proposal is much
more complex than mine. In my model people don't have to import stuff
*at all* so there is no problem and thus no need for aliases. And then
you also want to make the namespace model "non flat" by introducing
inheritance between namespaces? I rest my case... :)

regards, Göran



More information about the Squeak-dev mailing list