Exporting Namespaces

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Exporting Namespaces

Michael van der Gulik-2
Hi all.

I'm currently implementing hierarchical Namespaces for Squeak, which I need for another project of mine. The current design is as follows:

- Each Namespace is a Dictionary mapping #names to "global" variables, classes, and sub-Namespaces.
- Each Namespace has a list of imports, which is a list of other Namespaces that are searched when a global variable name is used.

Source code here: http://www.squeaksource.com/SecureSqueak .

So when writing code, your class resides in a particular Namespace, and if you refer to a global variable, it is searched for in that Namespace followed by that Namespace's import list.

Currently, I've got the basic Namespace structure working, and I've been making a special browser, based on the PlusTools browser that uses ToolBuilder, that lets you browse a Namespace hierarchy and manage import lists.

Now, the question: How can I get Namespaces out of an image? I've had the following ideas, and I'd like people's comments:

- Namespace source code could be stored in squeak.sources, and filed out as they are now but with a few changes to class definitions.

Advantages: Most tools in Squeak would probably still work.
Disadvantages: Not backwards compatible, tools will need modifying a bit.

- Namespace source code, rather than being stored in squeak.sources, could be stored in a hierarchy of directories under individual files for each class, with version history stored in or alongside those files.

Advantages: You can use Subversion / CVS with this approach, or in the worst case, use a text editor.
Disadvantages: ...

- Namespace source code could be kept only in the image. Source code would be a Text object.

Advantages: You get to keep formatting info.
Disadvantages: If the image breaks, so does your source code.

Keeping source code in the image would mean that some mechanism of importing or exporting a Namespace tree would be needed. I've thought about  modifying Monticello. Currently, .mcz packages contain a snapshot/source.st which could be replaced with a directory tree of source code.

Thoughts? Can we live without changesets if you had good Monticello support? Can squeak.sources be ditched, instead storing source code in the image?

Michael.


Reply | Threaded
Open this post in threaded view
|

RE: Exporting Namespaces

Alan L. Lovejoy
Michael,
 
I don't understand your issue.  You say you want to "get Namespaces out of an image."  What, precisely, do you mean by that? What's the connection between having namespaces and needing to change the location-of-record for method sources?  Shouldn't those two issues be indepedent of each other?
 
Namespaces should do the following:
 
    1) **Transparently** replace "shared pool dictionaries"; and
 
    2) Enable "the same global name" to refer to different values in the context of different classes (or perhaps even different methods) without requiring any change to existing method sources or to the syntax of variable names (Namespaces should be completely orthogonal to syntactical issues, such as whether to enable "MyPackage.MyClass" or "MyPackage::MyClass" or "MyPackage#MyClass" as new syntax for referring to variables in specific namespaces.)
 
--Alan


Reply | Threaded
Open this post in threaded view
|

Re: Exporting Namespaces

Michael van der Gulik-2
In reply to this post by Michael van der Gulik-2


On 2/19/07, Alan Lovejoy <[hidden email]> wrote:
Michael,
 
I don't understand your issue.  You say you want to "get Namespaces out of an image."  What, precisely, do you mean by that? What's the connection between having namespaces and needing to change the location-of-record for method sources?  Shouldn't those two issues be indepedent of each other?

I have an image. In that image is a Namespace. I need to get that Namespace and the source for the classes in that Namespace out of that image and in to another image somehow - usually done using e.g. Monticello, filings stuff out, etc.

The format for SqueakV9.sources, squeak.changes, changesets and file-outs will have to change a bit if they were to support Namespaces. Rather than changing the format, another option is to chuck everything out the window and use a different system, such as keeping the source code and version information in the image as Text objects. I'm just wanting people's opinions on the technical merits of the options I mentioned in the root of this thread.


Namespaces should do the following:
 
    1) **Transparently** replace "shared pool dictionaries"; and
 
    2) Enable "the same global name" to refer to different values in the context of different classes (or perhaps even different methods) without requiring any change to existing method sources or to the syntax of variable names (Namespaces should be completely orthogonal to syntactical issues, such as whether to enable "MyPackage.MyClass" or "MyPackage::MyClass" or "MyPackage#MyClass" as new syntax for referring to variables in specific namespaces.)

Ahh... yea... they do all that now. I haven't tested it yet though.

Michael.




Reply | Threaded
Open this post in threaded view
|

RE: Exporting Namespaces

Alan L. Lovejoy
 

 <Michael van der Gulik> I have an image. In that image is a Namespace. I need to get that Namespace and the source for the classes in that Namespace out of that image and in to another image somehow - usually done using e.g. Monticello, filings stuff out, etc.

The format for SqueakV9.sources, squeak.changes, changesets and file-outs will have to change a bit if they were to support Namespaces. Rather than changing the format, another option is to chuck everything out the window and use a different system, such as keeping the source code and version information in the image as Text objects. I'm just wanting people's opinions on the technical merits of the options I mentioned in the root of this thread. < / Michael van der Gulik>

Ok, thanks for the explanation.  I think I now understand your problem.
 
My suggestion: Namespaces should be constructed by message sends, just like classes are constructed by message sends.  The instructions to create/modify namespaces should be encoded in a file out as "do it" chunks--again, just like class definitions.  This may not be the ideal solution in the long run, but it's the only workable/acceptable solution initially.
 
I would avoid changing the canonical message sends that define classes if at all possible.  If necessary, send additional namespace-related messages to classes in separate "do it" chunks.
 
The namespace-related "do it" chunks should silently short-circuit if the receiving image doesn't support namespaces (although a single warning message for each file-in might be nice--perhaps a UUID for each file-out would make that possible.)  Or, perhaps your Namespace module could be auto-installed from SqueakMap or SqueakSource, when needed.
 
Evolution almost always works a lot better than revolution.  Don't fight against the tide. Go with the flow.  When life hands you a lemon, make lemonade.
 
--Alan


Reply | Threaded
Open this post in threaded view
|

Re: Exporting Namespaces

Michael van der Gulik-2
In reply to this post by Michael van der Gulik-2


On 2/19/07, Alan Lovejoy <[hidden email]> wrote:
 

Ok, thanks for the explanation.  I think I now understand your problem.
 
My suggestion: Namespaces should be constructed by message sends, just like classes are constructed by message sends.  The instructions to create/modify namespaces should be encoded in a file out as "do it" chunks--again, just like class definitions.  This may not be the ideal solution in the long run, but it's the only workable/acceptable solution initially.

I would avoid changing the canonical message sends that define classes if at all possible.  If necessary, send additional namespace-related messages to classes in separate "do it" chunks.


It certainly isn't the /only/ workable/acceptable solution, and I'm not worried about backwards compatibility unless it's cheap.

But this is a good option. It has the advantage of being able to load code that uses Namespaces into a non-Namespace-able image.
 
Evolution almost always works a lot better than revolution.

Evolution is the process of keeping the obfuscated mess that didn't die.

Michael.




Reply | Threaded
Open this post in threaded view
|

RE: Exporting Namespaces

J J-6
In reply to this post by Michael van der Gulik-2
>From: "Michael van der Gulik" <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: "The general-purpose Squeak developers
>list"<[hidden email]>
>Subject: Exporting Namespaces
>Date: Mon, 19 Feb 2007 11:03:58 +1300
>
>- Namespace source code, rather than being stored in squeak.sources, could
>be stored in a hierarchy of directories under individual files for each
>class, with version history stored in or alongside those files.
>
>Advantages: You can use Subversion / CVS with this approach, or in the
>worst
>case, use a text editor.
>Disadvantages: ...

Subversion and especially CVS suck badly.  darcs is much simpler and easy to
use.  But even better would be to integrate some of the ideas of darcs
(theory of patches) directly into Squeak for easier manipulation of changes
within the image.

_________________________________________________________________
Play Flexicon: the crossword game that feeds your brain. PLAY now for FREE. 
  http://zone.msn.com/en/flexicon/default.htm?icid=flexicon_hmtagline


Reply | Threaded
Open this post in threaded view
|

RE: Exporting Namespaces

J J-6
In reply to this post by Michael van der Gulik-2
+1.  Just please, no colons.  Or at least make it configurable so I don't
have to see it. :)  The best would be if direct namespace access looked like
normal message sends.

>From: "Alan Lovejoy" <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: "'The general-purpose Squeak developers
>list'"<[hidden email]>
>Subject: RE: Exporting Namespaces
>Date: Sun, 18 Feb 2007 17:40:35 -0800
>
>
>
>  <Michael van der Gulik> I have an image. In that image is a Namespace. I
>need to get that Namespace and the source for the classes in that Namespace
>out of that image and in to another image somehow - usually done using e.g.
>Monticello, filings stuff out, etc.
>
>The format for SqueakV9.sources, squeak.changes, changesets and file-outs
>will have to change a bit if they were to support Namespaces. Rather than
>changing the format, another option is to chuck everything out the window
>and use a different system, such as keeping the source code and version
>information in the image as Text objects. I'm just wanting people's
>opinions
>on the technical merits of the options I mentioned in the root of this
>thread. < / Michael van der Gulik>
>
>Ok, thanks for the explanation.  I think I now understand your problem.
>
>My suggestion: Namespaces should be constructed by message sends, just like
>classes are constructed by message sends.  The instructions to
>create/modify
>namespaces should be encoded in a file out as "do it" chunks--again, just
>like class definitions.  This may not be the ideal solution in the long
>run,
>but it's the only workable/acceptable solution initially.
>
>I would avoid changing the canonical message sends that define classes if
>at
>all possible.  If necessary, send additional namespace-related messages to
>classes in separate "do it" chunks.
>
>The namespace-related "do it" chunks should silently short-circuit if the
>receiving image doesn't support namespaces (although a single warning
>message for each file-in might be nice--perhaps a UUID for each file-out
>would make that possible.)  Or, perhaps your Namespace module could be
>auto-installed from SqueakMap or SqueakSource, when needed.
>
>Evolution almost always works a lot better than revolution.  Don't fight
>against the tide. Go with the flow.  When life hands you a lemon, make
>lemonade.
>
>--Alan


>

_________________________________________________________________
Don’t miss your chance to WIN 10 hours of private jet travel from Microsoft®
Office Live http://clk.atdmt.com/MRT/go/mcrssaub0540002499mrt/direct/01/


Reply | Threaded
Open this post in threaded view
|

Re: Exporting Namespaces

Michael van der Gulik-2


On 2/21/07, J J <[hidden email]> wrote:
+1.  Just please, no colons.  Or at least make it configurable so I don't
have to see it. :)  The best would be if direct namespace access looked like
normal message sends.

What would you suggest? I could use any non-whitespace character, I think.

Currently I'm using dots:

a := Collections.Arrayed.Array new: 5.

Usually though you'd just use:

a := Array new: 5.

and add the Collections.Arrayed Namespace to your import list. Each import list is common to all classes at a certain branch of the Namespace hierarchy, so the dotted notation is only useful if, in the same branch of the Namespace hierarchy, you want to use two classes (or global vars) that have the same name.

I'm not entirely sure how I'd implement your message sending idea, and it doesn't particularly feel "right" to me. I assume you mean:

a := Collections Arrayed Array new: 5.

Michael.


Reply | Threaded
Open this post in threaded view
|

Re: Exporting Namespaces

J J-6
>From: "Michael van der Gulik" <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: "The general-purpose Squeak developers
>list"<[hidden email]>
>Subject: Re: Exporting Namespaces
>Date: Wed, 21 Feb 2007 10:05:30 +1300
>
>What would you suggest? I could use any non-whitespace character, I think.
>
>Currently I'm using dots:
>
>a := Collections.Arrayed.Array new: 5.

I guess I could live with that if the guys who write the parser can. :)

>Usually though you'd just use:
>
>a := Array new: 5.
>
>and add the Collections.Arrayed Namespace to your import list. Each import
>list is common to all classes at a certain branch of the Namespace
>hierarchy, so the dotted notation is only useful if, in the same branch of
>the Namespace hierarchy, you want to use two classes (or global vars) that
>have the same name.

When you say "global vars" you mean classes right?

And how does the import work?  This is one thing I am concerned about:  In
python, your "unit of work" is a file.  So you look at the top and see the
imports and you know they are valid for *this file" (or if you import in a
local scope it extends to the end of that scope).  In smalltalk the compiled
"unit of work" is a method, no?  My import/export list is going to have to
be in the class definition right?

I know these are things that can be overcome with the tools (maybe show the
fully qualified class on mouseover), but it is just something to think
about.  Oh, and if a base class imports a bunch of stuff does a derived
class get it too, or do I have to specify the same imports over and over?  I
suppose you could have a default import (e.g. Core.*), package imports and
class imports.

>I'm not entirely sure how I'd implement your message sending idea, and it
>doesn't particularly feel "right" to me. I assume you mean:
>
>a := Collections Arrayed Array new: 5.
>
>Michael.

No, actually my favorite so far was from (I believe) Gemstone.  As I recall,
it was something like:

((Collections at: #Arrayed) at: #Array) new: 5.

Well, something much nicer looking then that I think.  And as you said, you
don't normally have to do this.  But the advantage (to me) of having it be
done with a message send syntax is that imports and the like could be done
with that as well, thereby making it easier to do method level imports
without having to resort to pragmas or something.

_________________________________________________________________
Find a local pizza place, movie theater, and more….then map the best route!
http://maps.live.com/?icid=hmtag1&FORM=MGAC01


Reply | Threaded
Open this post in threaded view
|

RE: Exporting Namespaces

jgfoster
The traditional Smalltalk approach to namespaces is to have the root of the
object graph be a SystemDictionary that holds a reference to itself in the
key #'Smalltalk'. When compiling methods, globals (including classes) are
looked up in this single dictionary.

In GemStone namespaces are supported by the use of a list of dictionaries
which are searched at compile time for a name. The root of the object graph
is AllUsers--an instance of UserProfileSet which holds instances of
UserProfile. Each UserProfile holds a reference to a SymbolList, a subclass
of Array that holds instances of SymbolDictionary. When you compile a method
you supply an instance of SymbolList that will be used to look up globals
(including classes). The SymbolList can be your default, the default for
another user, or one that you created on the fly with specific dictionaries
you want to be visible (in a particular order).

You can have the same key in multiple dictionaries, each having different
values. If you want to get to the value in a different dictionary, then you
navigate to that dictionary:

((AllUsers userWithId: 'DataCurator') symbolList
        objectNamed: 'Globals') at: #'Array'.

With GemStone you can have an image in which Swazoo, Hyper, KomHttpServer,
Monticello, Seaside, etc., are all present (each was loaded and compiled so
that it references its own classes and prerequisites). A user can have
visibility to a variety of packages but the packages need not have
visibility to each other.

James


> -----Original Message-----
> From: [hidden email] [mailto:squeak-dev-
> [hidden email]] On Behalf Of J J
> Sent: Friday, February 23, 2007 8:14 AM
> To: [hidden email]
> Subject: Re: Exporting Namespaces
>
> >From: "Michael van der Gulik" <[hidden email]>
> >Reply-To: The general-purpose Squeak developers
> >list<[hidden email]>
> >To: "The general-purpose Squeak developers
> >list"<[hidden email]>
> >Subject: Re: Exporting Namespaces
> >Date: Wed, 21 Feb 2007 10:05:30 +1300
> >
> >What would you suggest? I could use any non-whitespace character, I
> think.
> >
> >Currently I'm using dots:
> >
> >a := Collections.Arrayed.Array new: 5.
>
> I guess I could live with that if the guys who write the parser can. :)
>
> >Usually though you'd just use:
> >
> >a := Array new: 5.
> >
> >and add the Collections.Arrayed Namespace to your import list. Each
> import
> >list is common to all classes at a certain branch of the Namespace
> >hierarchy, so the dotted notation is only useful if, in the same branch
> of
> >the Namespace hierarchy, you want to use two classes (or global vars)
> that
> >have the same name.
>
> When you say "global vars" you mean classes right?
>
> And how does the import work?  This is one thing I am concerned about:  In
> python, your "unit of work" is a file.  So you look at the top and see the
> imports and you know they are valid for *this file" (or if you import in a
> local scope it extends to the end of that scope).  In smalltalk the
> compiled
> "unit of work" is a method, no?  My import/export list is going to have to
> be in the class definition right?
>
> I know these are things that can be overcome with the tools (maybe show
> the
> fully qualified class on mouseover), but it is just something to think
> about.  Oh, and if a base class imports a bunch of stuff does a derived
> class get it too, or do I have to specify the same imports over and over?
> I
> suppose you could have a default import (e.g. Core.*), package imports and
> class imports.
>
> >I'm not entirely sure how I'd implement your message sending idea, and it
> >doesn't particularly feel "right" to me. I assume you mean:
> >
> >a := Collections Arrayed Array new: 5.
> >
> >Michael.
>
> No, actually my favorite so far was from (I believe) Gemstone.  As I
> recall,
> it was something like:
>
> ((Collections at: #Arrayed) at: #Array) new: 5.
>
> Well, something much nicer looking then that I think.  And as you said,
> you
> don't normally have to do this.  But the advantage (to me) of having it be
> done with a message send syntax is that imports and the like could be done
> with that as well, thereby making it easier to do method level imports
> without having to resort to pragmas or something.
>
> _________________________________________________________________
> Find a local pizza place, movie theater, and more..then map the best
> route!
> http://maps.live.com/?icid=hmtag1&FORM=MGAC01
>



Reply | Threaded
Open this post in threaded view
|

Re: Exporting Namespaces

Michael van der Gulik-2
In reply to this post by J J-6


On 2/24/07, J J <[hidden email]> wrote:


>Usually though you'd just use:
>
>a := Array new: 5.
>
>and add the Collections.Arrayed Namespace to your import list. Each import
>list is common to all classes at a certain branch of the Namespace
>hierarchy, so the dotted notation is only useful if, in the same branch of
>the Namespace hierarchy, you want to use two classes (or global vars) that
>have the same name.

When you say "global vars" you mean classes right?

I'll answer this question in more detail below...

And how does the import work?  This is one thing I am concerned about:  In
python, your "unit of work" is a file.  So you look at the top and see the
imports and you know they are valid for *this file" (or if you import in a
local scope it extends to the end of that scope).  In smalltalk the compiled
"unit of work" is a method, no?  My import/export list is going to have to
be in the class definition right?

No - I've designed it so that the import list is part of the current local Namespace and is shared by all classes at that level of nesting in that Namespace. Note that this design isn't final; I'm going to see what pragmatically works best.

A Namespace is a Dictionary and has a list of imports. It maps #Names to objects, and those objects would be predominantly classes but could be any object in the current image.

When your code is compiled, I've changed it so that it searches for global variables first directly in that classes' namespace, and then in that namespace's import list. If the name uses the dot notation ( e.g. #'Collections.OrderedCollection') then it splits the name up first before searching.

An example: for #'Collections.OrderedCollection', it would first search for #Collections in the local Namespace for the class you're working with. If it isn't there, it then searches in the import list of that Namespace. When it finds #Collections (which would be another Namespace) in the import list, it then looks up #OrderedCollection within the #Collections Namespace.

I know these are things that can be overcome with the tools (maybe show the
fully qualified class on mouseover), but it is just something to think
about.  Oh, and if a base class imports a bunch of stuff does a derived
class get it too, or do I have to specify the same imports over and over?  I
suppose you could have a default import (e.g. Core.*), package imports and
class imports.

Erm... read the above. The imports of a base class have no effect on the imports of any subclasses. If they're in the same Namespace, they have the same import list. If they aren't, then they don't.

There are no default imports or class imports. There's also no such thing as a package in my schema.

>I'm not entirely sure how I'd implement your message sending idea, and it
>doesn't particularly feel "right" to me. I assume you mean:
>
>a := Collections Arrayed Array new: 5.
>
>Michael.

No, actually my favorite so far was from (I believe) Gemstone.  As I recall,
it was something like:

((Collections at: #Arrayed) at: #Array) new: 5.
 
Er... yuck.

Michael.