Hi all,
There's an old joke in the Squeak community about how we have a flame war about namespaces every few years and only newbies bring up the topic casually. Well, it seems we're overdue, so I'd like to do my bit for the community by keeping up the tradition.
I propose that Squeak 4.4, or perhaps 4.5, include support for more than one class with the same name. This will be a modest proposal, based on extending Dan's work on environments. The basic idea is this: an Environment is an object that implements a policy for binding names to objects during compilation.
This is in direct contrast to the Namespace implementation that VisualWorks uses. In VW the global namespace is divided up into a dot-delimited hierarchy, and there are mechanisms for resolving unqualified names. Environments, in contrast, are more like Newspeak modules. There's no universal mapping of names to objects, but rather different "points of view," where names resolve differently depending on which environment you're in.
The simplest and most common use for environments is to allow two classes with the same name to peacefully co-exist. We currently work around this problem with classname prefixes - MC in Monticello or WA in Seaside. With environments, we can do away with prefixes by creating a separate environment for each prefix that we're currently using.
An interesting example of this case that I've run across lately is Xtreams. In the original VW version, there's only one class that's publicly visible: the Incomplete exception that gets raised when a stream operation fails. The rest of the public API to the library is provided as extensions to classes in the base system. There's actually no need for code that uses Xtreams to refer to any of the stream classes. That leaves a lot of room for the implementation of Xtreams to change while keeping the API stable, and I'd like to be able to take advantage of this design in Squeak. With Environments, that's possible: we just create an environment to hold the Xtreams classes, import the base system, compile Xtreams, export Incomplete, and import Xtreams into our application's environment.
I've done a preliminary implementation, which lets me create an empty environment, file code into it and then browse and modify it with a standard browser. There's still lots of work to do, but I want to get a consensus among the core developers before tackling it. That way the changes can happen in the trunk and we don't have to worry about a difficult integration later.
I've attached a couple of screenshots. The first shows two browsers, one browsing the base image, the other browsing an environment with Seaside 3.0 loaded. The second is an explorer on the Seaside environment. The image where they were taken is available for download here:
http://www.wiresong.ca/downloads/Environments.zip
Flame away!
Colin
Wow. Best approach I've seen so far. Ever. Simple, direct, to the point. In particular after looking at the code - it is complete enough to be practically useful, yet simple enough so that things can be changed if they don't work out in the way expected. People who don't like it can completely ignore it, people who want to use it have something to work with. It's just like having your cake and eating it, too :-)
I would use it.
Cheers, - Andreas
Colin Putney-3 wrote
Hi all,
There's an old joke in the Squeak community about how we have a flame war about namespaces every few years and only newbies bring up the topic casually. Well, it seems we're overdue, so I'd like to do my bit for the community by keeping up the tradition.
I propose that Squeak 4.4, or perhaps 4.5, include support for more than one class with the same name. This will be a modest proposal, based on extending Dan's work on environments. The basic idea is this: an Environment is an object that implements a policy for binding names to objects during compilation.
This is in direct contrast to the Namespace implementation that VisualWorks uses. In VW the global namespace is divided up into a dot-delimited hierarchy, and there are mechanisms for resolving unqualified names. Environments, in contrast, are more like Newspeak modules. There's no universal mapping of names to objects, but rather different "points of view," where names resolve differently depending on which environment you're in.
The simplest and most common use for environments is to allow two classes with the same name to peacefully co-exist. We currently work around this problem with classname prefixes - MC in Monticello or WA in Seaside. With environments, we can do away with prefixes by creating a separate environment for each prefix that we're currently using.
An interesting example of this case that I've run across lately is Xtreams. In the original VW version, there's only one class that's publicly visible: the Incomplete exception that gets raised when a stream operation fails. The rest of the public API to the library is provided as extensions to classes in the base system. There's actually no need for code that uses Xtreams to refer to any of the stream classes. That leaves a lot of room for the implementation of Xtreams to change while keeping the API stable, and I'd like to be able to take advantage of this design in Squeak. With Environments, that's possible: we just create an environment to hold the Xtreams classes, import the base system, compile Xtreams, export Incomplete, and import Xtreams into our application's environment.
I've done a preliminary implementation, which lets me create an empty environment, file code into it and then browse and modify it with a standard browser. There's still lots of work to do, but I want to get a consensus among the core developers before tackling it. That way the changes can happen in the trunk and we don't have to worry about a difficult integration later.
I've attached a couple of screenshots. The first shows two browsers, one browsing the base image, the other browsing an environment with Seaside 3.0 loaded. The second is an explorer on the Seaside environment. The image where they were taken is available for download here:
http://www.wiresong.ca/downloads/Environments.zip
Flame away!
Colin
-- View this message in context: http://forum.world.st/Environments-tp4636629p4636657.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
On 26 June 2012 03:11, Colin Putney colin@wiresong.com wrote:
Hi all,
There's an old joke in the Squeak community about how we have a flame war about namespaces every few years and only newbies bring up the topic casually. Well, it seems we're overdue, so I'd like to do my bit for the community by keeping up the tradition.
I propose that Squeak 4.4, or perhaps 4.5, include support for more than one class with the same name. This will be a modest proposal, based on extending Dan's work on environments. The basic idea is this: an Environment is an object that implements a policy for binding names to objects during compilation.
This is in direct contrast to the Namespace implementation that VisualWorks uses. In VW the global namespace is divided up into a dot-delimited hierarchy, and there are mechanisms for resolving unqualified names. Environments, in contrast, are more like Newspeak modules. There's no universal mapping of names to objects, but rather different "points of view," where names resolve differently depending on which environment you're in.
The simplest and most common use for environments is to allow two classes with the same name to peacefully co-exist. We currently work around this problem with classname prefixes - MC in Monticello or WA in Seaside. With environments, we can do away with prefixes by creating a separate environment for each prefix that we're currently using.
An interesting example of this case that I've run across lately is Xtreams. In the original VW version, there's only one class that's publicly visible: the Incomplete exception that gets raised when a stream operation fails. The rest of the public API to the library is provided as extensions to classes in the base system. There's actually no need for code that uses Xtreams to refer to any of the stream classes. That leaves a lot of room for the implementation of Xtreams to change while keeping the API stable, and I'd like to be able to take advantage of this design in Squeak. With Environments, that's possible: we just create an environment to hold the Xtreams classes, import the base system, compile Xtreams, export Incomplete, and import Xtreams into our application's environment.
I've done a preliminary implementation, which lets me create an empty environment, file code into it and then browse and modify it with a standard browser. There's still lots of work to do, but I want to get a consensus among the core developers before tackling it. That way the changes can happen in the trunk and we don't have to worry about a difficult integration later.
I hate to disappoint the invitation for flaming, but I'm very happy for this to go into trunk.
(As an aside, Environments also shows that resumable exceptions express _delimited_ dynamic variables, exemplified by EnvironmentRequest. (These are dynamic variables that play nicely with delimited continuations; they close over _part_ of the dynamic environment.) I'll follow up with a longer mail hopefully today or tomorrow)
frank
I've attached a couple of screenshots. The first shows two browsers, one browsing the base image, the other browsing an environment with Seaside 3.0 loaded. The second is an explorer on the Seaside environment. The image where they were taken is available for download here:
http://www.wiresong.ca/downloads/Environments.zip
Flame away!
Colin
It sounds like a simple solution -- I do appreciate it's a pure OO solution rather introducing new syntax.
However, things tend to "sound" simple when I barely understand them. Perhaps a concrete example would help me -- the basic use-case: pretend I have an application called "Application" that wants to use both Magma and Seaside in the same image and each wants to define a "Session" class. They are developed by different developers. In this context, could you clarify some questions?
- Somewhere, the Application would need to define the "order" of the Environments it depends on so it can sometimes use unqualified names, is this correct? What would that code look like?
- What would the loading/initialization code look like that would put Magma's Session into its own environment?
- What would the code to access Magma's Session (instead of Seasides) look like from within one of Magma's methods?
- What would the code to access Magma's Session (instead of Seasides) look like from within one of Application's methods?
- What would the code to access Magma's Session (instead of Seasides) look like from a workspace (Global environment?)
It sounds like you're on to something to give Squeak a new a kung-fu move, thanks for pushing on this!
On Mon, Jun 25, 2012 at 9:11 PM, Colin Putney colin@wiresong.com wrote:
Hi all,
There's an old joke in the Squeak community about how we have a flame war about namespaces every few years and only newbies bring up the topic casually. Well, it seems we're overdue, so I'd like to do my bit for the community by keeping up the tradition.
I propose that Squeak 4.4, or perhaps 4.5, include support for more than one class with the same name. This will be a modest proposal, based on extending Dan's work on environments. The basic idea is this: an Environment is an object that implements a policy for binding names to objects during compilation.
This is in direct contrast to the Namespace implementation that VisualWorks uses. In VW the global namespace is divided up into a dot-delimited hierarchy, and there are mechanisms for resolving unqualified names. Environments, in contrast, are more like Newspeak modules. There's no universal mapping of names to objects, but rather different "points of view," where names resolve differently depending on which environment you're in.
The simplest and most common use for environments is to allow two classes with the same name to peacefully co-exist. We currently work around this problem with classname prefixes - MC in Monticello or WA in Seaside. With environments, we can do away with prefixes by creating a separate environment for each prefix that we're currently using.
An interesting example of this case that I've run across lately is Xtreams. In the original VW version, there's only one class that's publicly visible: the Incomplete exception that gets raised when a stream operation fails. The rest of the public API to the library is provided as extensions to classes in the base system. There's actually no need for code that uses Xtreams to refer to any of the stream classes. That leaves a lot of room for the implementation of Xtreams to change while keeping the API stable, and I'd like to be able to take advantage of this design in Squeak. With Environments, that's possible: we just create an environment to hold the Xtreams classes, import the base system, compile Xtreams, export Incomplete, and import Xtreams into our application's environment.
I've done a preliminary implementation, which lets me create an empty environment, file code into it and then browse and modify it with a standard browser. There's still lots of work to do, but I want to get a consensus among the core developers before tackling it. That way the changes can happen in the trunk and we don't have to worry about a difficult integration later.
I've attached a couple of screenshots. The first shows two browsers, one browsing the base image, the other browsing an environment with Seaside 3.0 loaded. The second is an explorer on the Seaside environment. The image where they were taken is available for download here:
http://www.wiresong.ca/downloads/Environments.zip
Flame away!
Colin
On Tue, Jun 26, 2012 at 8:38 AM, Chris Muller asqueaker@gmail.com wrote:
It sounds like a simple solution -- I do appreciate it's a pure OO solution rather introducing new syntax.
However, things tend to "sound" simple when I barely understand them. Perhaps a concrete example would help me -- the basic use-case: pretend I have an application called "Application" that wants to use both Magma and Seaside in the same image and each wants to define a "Session" class. They are developed by different developers. In this context, could you clarify some questions?
Sure, that sounds like a great use-case for Environments.
- Somewhere, the Application would need to define the "order" of the
Environments it depends on so it can sometimes use unqualified names, is this correct? What would that code look like?
Yes, that does need to be defined, but that definition shouldn't be part of Application. Application should just refer to the classes it needs and leave it up the environment to know where they are. That means that environment management is done in your development tools, and when building images. To set up the environments for Application you might do something like this:
(Environment name: 'Seaside') importSmalltalk; fileIn: 'Seaside.st'.
(Environment name: 'Magma') importSmalltalk; fileIn: 'Magma.st'.
(Environment name: 'Application') importSmalltalk; import: #Seaside; import: #Magma; fileIn: 'Application.st'.
- What would the loading/initialization code look like that would
put Magma's Session into its own environment?
You'd load all of Magma into the it's own environment, as above.
- What would the code to access Magma's Session (instead of
Seasides) look like from within one of Magma's methods?
From a design perspective, we don't want Seaside or Magma to depend on each
other. (Note that the Seaside and Magma environments don't import each other.) So within the Seaside and Magma environments, Session is unambiguous, and can just be referred to directly:
Session new
- What would the code to access Magma's Session (instead of
Seasides) look like from within one of Application's methods?
Ok, this is the bit that's slightly tricky. Application needs to use both Seaside sessions and Magma sessions, so we need to disambiguate. Application code should just use arbitrary names, like WASession and MaSession, or SeasideSession and MagmaSession if that's more aesthetically pleasing. Then it's up to the environment to sort them out. We'd do something like this:
(Environment name: 'Application') importSmalltalk; import: #Seaside aliases: {#Session -> #SeasideSession}; import: #Magma aliases: {#Session -> #MagmaSession}; fileIn: 'Application.st'.
Note that I haven't implemented imports (except for Smalltalk) or aliasing yet, so the protocol might end up being different.
- What would the code to access Magma's Session (instead of
Seasides) look like from a workspace (Global environment?)
The workspace would have an environment as well, and there's be some UI for manipulating it. So Magma's session might be called Session or MagmaSession, or whatever is convenient for that workspace. We might even do some kind of automatic importing similar to the way undeclared variables work are handled.
Great questions Chris, thanks.
Colin
(Environment name: 'Application') importSmalltalk; import: #Seaside aliases: {#Session -> #SeasideSession}; import: #Magma aliases: {#Session -> #MagmaSession}; fileIn: 'Application.st'.
Enhancement proposal:
how about making this aliasing automatic, happening when the 'ambiguous' class is imported to begin with? Eg when Magma is first imported (into its own environment), the system is smart enough to discover that there are two environments with a class named Session, and automatically creates an alias to both of them, by prefixing the environment name (Seaside and Magma, respectively) to the class name (SeasideSession, MagmaSession).
All users of the Seaside and Magma environments now have access to disambiguated names 'for free', without having the responsability to manually maintain a list of name-clashes in the world outside themselves (ie in the packages they depend on).
On Thu, Jun 28, 2012 at 2:34 AM, Michal michal-list@auf.net wrote:
(Environment name: 'Application') importSmalltalk; import: #Seaside aliases: {#Session -> #SeasideSession}; import: #Magma aliases: {#Session -> #MagmaSession}; fileIn: 'Application.st'.
Enhancement proposal:
how about making this aliasing automatic, happening when the 'ambiguous' class is imported to begin with? Eg when Magma is first imported (into its own environment), the system is smart enough to discover that there are two environments with a class named Session, and automatically creates an alias to both of them, by prefixing the environment name (Seaside and Magma, respectively) to the class name (SeasideSession, MagmaSession).
All users of the Seaside and Magma environments now have access to disambiguated names 'for free', without having the responsability to manually maintain a list of name-clashes in the world outside themselves (ie in the packages they depend on).
That's a great idea. There would have to be a way to turn it off and keep full control, but yeah, if we have a default policy for disambiguating that would be really useful. Thanks, Michal!
Colin
On Thu, Jun 28, 2012 at 7:00 PM, Colin Putney colin@wiresong.com wrote:
On Thu, Jun 28, 2012 at 2:34 AM, Michal michal-list@auf.net wrote:
(Environment name: 'Application') importSmalltalk; import: #Seaside aliases: {#Session -> #SeasideSession}; import: #Magma aliases: {#Session -> #MagmaSession}; fileIn: 'Application.st'.
Enhancement proposal:
how about making this aliasing automatic, happening when the 'ambiguous' class is imported to begin with? Eg when Magma is first imported (into its own environment), the system is smart enough to discover that there are two environments with a class named Session, and automatically creates an alias to both of them, by prefixing the environment name (Seaside and Magma, respectively) to the class name (SeasideSession, MagmaSession).
All users of the Seaside and Magma environments now have access to disambiguated names 'for free', without having the responsability to manually maintain a list of name-clashes in the world outside themselves (ie in the packages they depend on).
That's a great idea. There would have to be a way to turn it off and keep full control, but yeah, if we have a default policy for disambiguating that would be really useful. Thanks, Michal!
Colin
Well, maybe. If I understand this right, then when you alias a class, you refer to the alias in the code that is loaded later. If, however, a class was left unaliased originally (in an import) and was then referenced in the code depending on that import, but later a NEW environment import was introduced with the same class, then if the new importer automatically aliased both of these, the code wouldn't know which one to use. Which would be unfortunate.
In your Seaside / Magma example, could you leave one Session just as Session, and have the other aliased?
Maybe the auto-aliaser would need to detect that the new code references a dual-defined class, and asks which one it should use? in other words, 'partially' auto alias.
-Another Chris
Hi all!
On 06/29/2012 06:48 AM, Chris Cunningham wrote:
Maybe the auto-aliaser would need to detect that the new code references a dual-defined class, and asks which one it should use? in other words, 'partially' auto alias.
-Another Chris
Interesting, some of these last ideas would make the end user experience similar to my Namespace implementation (for the insatiably interested: http://swiki.krampe.se/gohu/32)
In that solution it works like this:
- Classes can optionally be named "Fruit::Orange" instead of just "Orange"
- When you look at source code with "Fruit::Orange" in it, it will "render in the browser" as just "Orange" iff there is just one Orange in the image. If there is also a "Colors::Orange" then it will automatically suddenly render in full.
- If you try to compile "Orange" (in a Workspace or in a method) the tools will throw up a popup menu asking if you meant "Fruit::Orange" or "Color::Orange". And it will autoexpand it to its full name when you select.
- "Prefix" also automatically refers to an instance of Namespace which is a global and acts like a Dictionary. Thus Namespaces are reified.
Well, that's about it. Essentially it is prefixes like we have today - but with a clear separator (::), and reification of Namespaces.
Being able to "pick another Namespace" when importing code (typically holding a map of these aliases so that code can still find its way) was never implemented but planned.
So you end up with two Fruit packages - the idea was that you can import one of them into another Namespace like OldFruit and the image would contain this knowledge so that other packages can still resolve references to OldFruit classes, and ask etc.
Anyway, intrigued to see where you end up! :)
regards, Göran
On Thu, Jun 28, 2012 at 9:48 PM, Chris Cunningham cunningham.cb@gmail.com wrote:
Well, maybe. If I understand this right, then when you alias a class, you refer to the alias in the code that is loaded later. If, however, a class was left unaliased originally (in an import) and was then referenced in the code depending on that import, but later a NEW environment import was introduced with the same class, then if the new importer automatically aliased both of these, the code wouldn't know which one to use. Which would be unfortunate.
First and foremost, auto-aliasing would have to be optional. There's always the escape hatch of being able to be explicit about everything, and get exactly what you want.
Second, you're talking about two different situations here. One is where you're setting up a new environment before it contains any code. In that case, you have to create the environment that the code expects to see—either code that's already written or the code you're about to write. Auto-aliasing provides an reasonable convention that handles that case well.
The other situation is where you add an import to an environment that already has code in it, introducing a name clash. There are three possible options:
1. Create an alias for the binding being imported. We know that the code already in the environment doesn't refer to it, so we just give it a new name and we're in good shape.
2. Create an alias for the existing binding. It requires updating the existing code to use the new name. If we have the RB installed, that's easy; if not, we can at least bring up a browser with all the references to the old name so the user can find them easily.
3. Alias both bindings. This gets us to where we'd have been if we'd done the import before any code was written. Again it requires updating all the existing references.
We could use auto-aliasing only with empty environments, or have a (configurable?) policy for handling name clashes, or just ask the user what to do. It doesn't have to be decided now; we'll cross that bridge when we get to it.
In your Seaside / Magma example, could you leave one Session just as Session, and have the other aliased?
Sure.
Maybe the auto-aliaser would need to detect that the new code references a dual-defined class, and asks which one it should use? in other words, 'partially' auto alias.
No. Auto aliasing would happen a namespace is being imported into an environment, not when code is being loaded. The idea is to resolve all ambiguities when constructing the environment, so that the compiler and dev tools can deal with a simple, one-to-one mapping from names to classes.
Colin
On 29.06.2012, at 08:57, Colin Putney wrote:
On Thu, Jun 28, 2012 at 9:48 PM, Chris Cunningham cunningham.cb@gmail.com wrote:
Well, maybe. If I understand this right, then when you alias a class, you refer to the alias in the code that is loaded later. If, however, a class was left unaliased originally (in an import) and was then referenced in the code depending on that import, but later a NEW environment import was introduced with the same class, then if the new importer automatically aliased both of these, the code wouldn't know which one to use. Which would be unfortunate.
First and foremost, auto-aliasing would have to be optional. There's always the escape hatch of being able to be explicit about everything, and get exactly what you want.
Second, you're talking about two different situations here. One is where you're setting up a new environment before it contains any code. In that case, you have to create the environment that the code expects to see—either code that's already written or the code you're about to write. Auto-aliasing provides an reasonable convention that handles that case well.
The other situation is where you add an import to an environment that already has code in it, introducing a name clash. There are three possible options:
- Create an alias for the binding being imported. We know that the
code already in the environment doesn't refer to it, so we just give it a new name and we're in good shape.
- Create an alias for the existing binding. It requires updating the
existing code to use the new name. If we have the RB installed, that's easy; if not, we can at least bring up a browser with all the references to the old name so the user can find them easily.
- Alias both bindings. This gets us to where we'd have been if we'd
done the import before any code was written. Again it requires updating all the existing references.
Or, do nothing at all. The new binding would simply be shadowed.
We could use auto-aliasing only with empty environments, or have a (configurable?) policy for handling name clashes, or just ask the user what to do. It doesn't have to be decided now; we'll cross that bridge when we get to it.
In your Seaside / Magma example, could you leave one Session just as Session, and have the other aliased?
Sure.
Maybe the auto-aliaser would need to detect that the new code references a dual-defined class, and asks which one it should use? in other words, 'partially' auto alias.
No. Auto aliasing would happen a namespace is being imported into an environment, not when code is being loaded. The idea is to resolve all ambiguities when constructing the environment, so that the compiler and dev tools can deal with a simple, one-to-one mapping from names to classes.
Colin
Maybe aliasing isn't the best solution to resolve ambiguities?
What if there was no aliasing, but names would strictly be resolved in order of import? That is exactly as your implementation currently works, right?
To refer to a shadowed global, one would have to explicitly request it from its environment, e.g.:
self environment: 'Magma' at: #Session
I like this better than aliasing because it shows what's happening when actually using it, not somewhere hidden at the import. It's even less magic :)
At least that's what I would strive for in an initial implementation. We can add bells and whistles later.
- Bert -
Bert Freudenberg wrote
Maybe aliasing isn't the best solution to resolve ambiguities?
What if there was no aliasing, but names would strictly be resolved in order of import? That is exactly as your implementation currently works, right?
To refer to a shadowed global, one would have to explicitly request it from its environment, e.g.:
self environment: 'Magma' at: #Session
I like this better than aliasing because it shows what's happening when actually using it, not somewhere hidden at the import. It's even less magic :)
At least that's what I would strive for in an initial implementation. We can add bells and whistles later.
+1. Adding convenience later sounds like a good strategy. It means there is time to find out what the actual patterns are once people start using it.
Cheers, - Andreas
-- View this message in context: http://forum.world.st/Environments-tp4636629p4637266.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
On Fri, Jun 29, 2012 at 3:32 AM, Bert Freudenberg bert@freudenbergs.de wrote:
Or, do nothing at all. The new binding would simply be shadowed.
Ah, good point. That's a fourth option.
Maybe aliasing isn't the best solution to resolve ambiguities?
What if there was no aliasing, but names would strictly be resolved in order of import? That is exactly as your implementation currently works, right?
Yes, although so far I've only imported Smalltalk, not other environments.
To refer to a shadowed global, one would have to explicitly request it from its environment, e.g.:
self environment: 'Magma' at: #Session
I like this better than aliasing because it shows what's happening when actually using it, not somewhere hidden at the import. It's even less magic :)
I don't like this at all. It's equivalent to a fully qualified class reference, ala VisualWorks Magma.Session or Göran's Magma::Session. Avoiding those is the whole point of this design. Environments should be invisible to the code inside them.
At least that's what I would strive for in an initial implementation. We can add bells and whistles later.
Yes, autoaliasing should certainly wait. As Andreas said, that'll let us see what aliasing strategies work well in practice. We can even hold off on manual aliasing until compiler and tool support is in place. (Not that aliasing is particularly hard to implement.)
That said, I don't want give up the idea of a completely flat namespace from the point of view of application code. That's throwing the baby out with the bathwater. It should appear to Application, that the authors of Seaside and Magma got together and coordinated their class names so that there were no prefixes and no clashes.
Colin
On 29.06.2012, at 16:40, Colin Putney wrote:
On Fri, Jun 29, 2012 at 3:32 AM, Bert Freudenberg bert@freudenbergs.de wrote:
Or, do nothing at all. The new binding would simply be shadowed.
Ah, good point. That's a fourth option.
Maybe aliasing isn't the best solution to resolve ambiguities?
What if there was no aliasing, but names would strictly be resolved in order of import? That is exactly as your implementation currently works, right?
Yes, although so far I've only imported Smalltalk, not other environments.
To refer to a shadowed global, one would have to explicitly request it from its environment, e.g.:
self environment: 'Magma' at: #Session
I like this better than aliasing because it shows what's happening when actually using it, not somewhere hidden at the import. It's even less magic :)
I don't like this at all. It's equivalent to a fully qualified class reference, ala VisualWorks Magma.Session or Göran's Magma::Session. Avoiding those is the whole point of this design. Environments should be invisible to the code inside them.
How is this different from having to use "MagmaSession", if the class is actually named "Session", in the Magma environment?
The code *has* to differentiate if it needs to use the same global from two different environments.
- Bert -
At least that's what I would strive for in an initial implementation. We can add bells and whistles later.
Yes, autoaliasing should certainly wait. As Andreas said, that'll let us see what aliasing strategies work well in practice. We can even hold off on manual aliasing until compiler and tool support is in place. (Not that aliasing is particularly hard to implement.)
That said, I don't want give up the idea of a completely flat namespace from the point of view of application code. That's throwing the baby out with the bathwater. It should appear to Application, that the authors of Seaside and Magma got together and coordinated their class names so that there were no prefixes and no clashes.
Colin
On Fri, Jun 29, 2012 at 7:47 AM, Bert Freudenberg bert@freudenbergs.de wrote:
I don't like this at all. It's equivalent to a fully qualified class reference, ala VisualWorks Magma.Session or Göran's Magma::Session. Avoiding those is the whole point of this design. Environments should be invisible to the code inside them.
How is this different from having to use "MagmaSession", if the class is actually named "Session", in the Magma environment?
The code *has* to differentiate if it needs to use the same global from two different environments.
Yes, the code has to differentiate. But we do it by having two names for the same class, rather than having to classes with the same name. To Seaside it's Session, to Application it's SeasideSession. As far as Application is concerned, it's a happy coincidence that Seaside and Magma don't have any name clashes.
Today we achieve that lack of clashes by coordinating with other developers. Chris agrees not to create any classes that start with 'WA' and the Seaside team agrees not to create any classes that start with 'Ma'. With environments, Chris doesn't have to coordinate with the Seaside team and the policy doesn't have to set in advance.
The developer of Application gets to set the policy for how his dependencies will be handled. He might decide that he doesn't need to refer to Magma sessions directly and let that class be shadowed, or that Magma sessions are really more like Engagements, or that MagmaSession is nicer or that MaSession is fine. Maybe he wants to use WA and Ma to remind himself where a class comes from, or maybe he would rather names be clean and simple.
But whatever he decides, he writes Application code as though the community had conspired to make his particular use case easy. Once Application is written, it depends on certain classes having particular names, but it doesn't have any idea how its environment is organized. Even if Seaside 4.0 is organized differently, we can make a different set of imports and aliases to provide Application with the environment that it needs.
Colin
This namespace solution is just for globals/class names correct? There could still potentially be method-name conflicts for extensions to classes in the Smalltalk environment, right?
On Mon, Jun 25, 2012 at 9:11 PM, Colin Putney colin@wiresong.com wrote:
Hi all,
There's an old joke in the Squeak community about how we have a flame war about namespaces every few years and only newbies bring up the topic casually. Well, it seems we're overdue, so I'd like to do my bit for the community by keeping up the tradition.
I propose that Squeak 4.4, or perhaps 4.5, include support for more than one class with the same name. This will be a modest proposal, based on extending Dan's work on environments. The basic idea is this: an Environment is an object that implements a policy for binding names to objects during compilation.
This is in direct contrast to the Namespace implementation that VisualWorks uses. In VW the global namespace is divided up into a dot-delimited hierarchy, and there are mechanisms for resolving unqualified names. Environments, in contrast, are more like Newspeak modules. There's no universal mapping of names to objects, but rather different "points of view," where names resolve differently depending on which environment you're in.
The simplest and most common use for environments is to allow two classes with the same name to peacefully co-exist. We currently work around this problem with classname prefixes - MC in Monticello or WA in Seaside. With environments, we can do away with prefixes by creating a separate environment for each prefix that we're currently using.
An interesting example of this case that I've run across lately is Xtreams. In the original VW version, there's only one class that's publicly visible: the Incomplete exception that gets raised when a stream operation fails. The rest of the public API to the library is provided as extensions to classes in the base system. There's actually no need for code that uses Xtreams to refer to any of the stream classes. That leaves a lot of room for the implementation of Xtreams to change while keeping the API stable, and I'd like to be able to take advantage of this design in Squeak. With Environments, that's possible: we just create an environment to hold the Xtreams classes, import the base system, compile Xtreams, export Incomplete, and import Xtreams into our application's environment.
I've done a preliminary implementation, which lets me create an empty environment, file code into it and then browse and modify it with a standard browser. There's still lots of work to do, but I want to get a consensus among the core developers before tackling it. That way the changes can happen in the trunk and we don't have to worry about a difficult integration later.
I've attached a couple of screenshots. The first shows two browsers, one browsing the base image, the other browsing an environment with Seaside 3.0 loaded. The second is an explorer on the Seaside environment. The image where they were taken is available for download here:
http://www.wiresong.ca/downloads/Environments.zip
Flame away!
Colin
On 26 June 2012 17:05, Chris Muller asqueaker@gmail.com wrote:
This namespace solution is just for globals/class names correct? There could still potentially be method-name conflicts for extensions to classes in the Smalltalk environment, right?
Preventing method conflicts is a whole other kettle of fish. Environments doesn't address this. (There are some interesting things in the avoid-monkey-patch-clashing area, like "selector namespaces", and classboxes, and probably some other things I don't know of.)
frank
On Mon, Jun 25, 2012 at 9:11 PM, Colin Putney colin@wiresong.com wrote:
Hi all,
There's an old joke in the Squeak community about how we have a flame war about namespaces every few years and only newbies bring up the topic casually. Well, it seems we're overdue, so I'd like to do my bit for the community by keeping up the tradition.
I propose that Squeak 4.4, or perhaps 4.5, include support for more than one class with the same name. This will be a modest proposal, based on extending Dan's work on environments. The basic idea is this: an Environment is an object that implements a policy for binding names to objects during compilation.
This is in direct contrast to the Namespace implementation that VisualWorks uses. In VW the global namespace is divided up into a dot-delimited hierarchy, and there are mechanisms for resolving unqualified names. Environments, in contrast, are more like Newspeak modules. There's no universal mapping of names to objects, but rather different "points of view," where names resolve differently depending on which environment you're in.
The simplest and most common use for environments is to allow two classes with the same name to peacefully co-exist. We currently work around this problem with classname prefixes - MC in Monticello or WA in Seaside. With environments, we can do away with prefixes by creating a separate environment for each prefix that we're currently using.
An interesting example of this case that I've run across lately is Xtreams. In the original VW version, there's only one class that's publicly visible: the Incomplete exception that gets raised when a stream operation fails. The rest of the public API to the library is provided as extensions to classes in the base system. There's actually no need for code that uses Xtreams to refer to any of the stream classes. That leaves a lot of room for the implementation of Xtreams to change while keeping the API stable, and I'd like to be able to take advantage of this design in Squeak. With Environments, that's possible: we just create an environment to hold the Xtreams classes, import the base system, compile Xtreams, export Incomplete, and import Xtreams into our application's environment.
I've done a preliminary implementation, which lets me create an empty environment, file code into it and then browse and modify it with a standard browser. There's still lots of work to do, but I want to get a consensus among the core developers before tackling it. That way the changes can happen in the trunk and we don't have to worry about a difficult integration later.
I've attached a couple of screenshots. The first shows two browsers, one browsing the base image, the other browsing an environment with Seaside 3.0 loaded. The second is an explorer on the Seaside environment. The image where they were taken is available for download here:
http://www.wiresong.ca/downloads/Environments.zip
Flame away!
Colin
Colin,
Be aware that code written to run in namespaces will be much more difficult to port to platforms with different or no namespace implementations. A portable solution 9not to be confused with a portable implementation) would be preferable and without looking at details, I'd guess that you are going down the portable route, especially since you are not leaning on syntax...
Dale
----- Original Message ----- | From: "Colin Putney" colin@wiresong.com | To: "Squeak-Dev developers list" squeak-dev@lists.squeakfoundation.org | Sent: Monday, June 25, 2012 7:11:18 PM | Subject: [squeak-dev] Environments | | Hi all, | | There's an old joke in the Squeak community about how we have a flame | war about namespaces every few years and only newbies bring up the | topic casually. Well, it seems we're overdue, so I'd like to do my | bit | for the community by keeping up the tradition. | | I propose that Squeak 4.4, or perhaps 4.5, include support for more | than one class with the same name. This will be a modest proposal, | based on extending Dan's work on environments. The basic idea is | this: | an Environment is an object that implements a policy for binding | names | to objects during compilation. | | This is in direct contrast to the Namespace implementation that | VisualWorks uses. In VW the global namespace is divided up into a | dot-delimited hierarchy, and there are mechanisms for resolving | unqualified names. Environments, in contrast, are more like Newspeak | modules. There's no universal mapping of names to objects, but rather | different "points of view," where names resolve differently depending | on which environment you're in. | | The simplest and most common use for environments is to allow two | classes with the same name to peacefully co-exist. We currently work | around this problem with classname prefixes - MC in Monticello or WA | in Seaside. With environments, we can do away with prefixes by | creating a separate environment for each prefix that we're currently | using. | | An interesting example of this case that I've run across lately is | Xtreams. In the original VW version, there's only one class that's | publicly visible: the Incomplete exception that gets raised when a | stream operation fails. The rest of the public API to the library is | provided as extensions to classes in the base system. There's | actually | no need for code that uses Xtreams to refer to any of the stream | classes. That leaves a lot of room for the implementation of Xtreams | to change while keeping the API stable, and I'd like to be able to | take advantage of this design in Squeak. With Environments, that's | possible: we just create an environment to hold the Xtreams classes, | import the base system, compile Xtreams, export Incomplete, and | import | Xtreams into our application's environment. | | I've done a preliminary implementation, which lets me create an empty | environment, file code into it and then browse and modify it with a | standard browser. There's still lots of work to do, but I want to get | a consensus among the core developers before tackling it. That way | the | changes can happen in the trunk and we don't have to worry about a | difficult integration later. | | I've attached a couple of screenshots. The first shows two browsers, | one browsing the base image, the other browsing an environment with | Seaside 3.0 loaded. The second is an explorer on the Seaside | environment. The image where they were taken is available for | download | here: | | http://www.wiresong.ca/downloads/Environments.zip | | | Flame away! | | Colin | | |
On 26 June 2012 17:26, Dale Henrichs dhenrich@vmware.com wrote:
Colin,
Be aware that code written to run in namespaces will be much more difficult to port to platforms with different or no namespace implementations. A portable solution 9not to be confused with a portable implementation) would be preferable and without looking at details, I'd guess that you are going down the portable route, especially since you are not leaning on syntax...
One non-portable part would be the ClassBuilder extensions! That lets you plug a new class into an Environment. I'm not sure how you'd coax an external compiler (Gemstone) into installing a new class into your new, isolated, environment.
frank
Dale
----- Original Message ----- | From: "Colin Putney" colin@wiresong.com | To: "Squeak-Dev developers list" squeak-dev@lists.squeakfoundation.org | Sent: Monday, June 25, 2012 7:11:18 PM | Subject: [squeak-dev] Environments | | Hi all, | | There's an old joke in the Squeak community about how we have a flame | war about namespaces every few years and only newbies bring up the | topic casually. Well, it seems we're overdue, so I'd like to do my | bit | for the community by keeping up the tradition. | | I propose that Squeak 4.4, or perhaps 4.5, include support for more | than one class with the same name. This will be a modest proposal, | based on extending Dan's work on environments. The basic idea is | this: | an Environment is an object that implements a policy for binding | names | to objects during compilation. | | This is in direct contrast to the Namespace implementation that | VisualWorks uses. In VW the global namespace is divided up into a | dot-delimited hierarchy, and there are mechanisms for resolving | unqualified names. Environments, in contrast, are more like Newspeak | modules. There's no universal mapping of names to objects, but rather | different "points of view," where names resolve differently depending | on which environment you're in. | | The simplest and most common use for environments is to allow two | classes with the same name to peacefully co-exist. We currently work | around this problem with classname prefixes - MC in Monticello or WA | in Seaside. With environments, we can do away with prefixes by | creating a separate environment for each prefix that we're currently | using. | | An interesting example of this case that I've run across lately is | Xtreams. In the original VW version, there's only one class that's | publicly visible: the Incomplete exception that gets raised when a | stream operation fails. The rest of the public API to the library is | provided as extensions to classes in the base system. There's | actually | no need for code that uses Xtreams to refer to any of the stream | classes. That leaves a lot of room for the implementation of Xtreams | to change while keeping the API stable, and I'd like to be able to | take advantage of this design in Squeak. With Environments, that's | possible: we just create an environment to hold the Xtreams classes, | import the base system, compile Xtreams, export Incomplete, and | import | Xtreams into our application's environment. | | I've done a preliminary implementation, which lets me create an empty | environment, file code into it and then browse and modify it with a | standard browser. There's still lots of work to do, but I want to get | a consensus among the core developers before tackling it. That way | the | changes can happen in the trunk and we don't have to worry about a | difficult integration later. | | I've attached a couple of screenshots. The first shows two browsers, | one browsing the base image, the other browsing an environment with | Seaside 3.0 loaded. The second is an explorer on the Seaside | environment. The image where they were taken is available for | download | here: | | http://www.wiresong.ca/downloads/Environments.zip | | | Flame away! | | Colin | | |
Frank,
As far as GemStone is concerned we've had separate environments for classes for a very long time. Instead of a Smalltalk dictionary, GemStone does global lookups using a list of dictionaries (SymbolList) and this list can be dynamically adjusted by the user. So in the end, I'd think that it would be straightforward to add this type of namespace to GemStone.
We've also got dynamic lookups for methods as well ... it's what we've used make it possible to run Ruby in a Smalltalk environment and it's what we use in GLASS for the Squeak/Pharo compatibility later ... I haven't looked at what it would take to isolate the method look up to an environment (i.e., environment-specific extension methods to shared classes), but it's something that we'd eventually like to do.
Dale
----- Original Message ----- | From: "Frank Shearar" frank.shearar@gmail.com | To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org | Sent: Tuesday, June 26, 2012 9:30:28 AM | Subject: Re: [squeak-dev] Environments | | On 26 June 2012 17:26, Dale Henrichs dhenrich@vmware.com wrote: | > Colin, | > | > Be aware that code written to run in namespaces will be much more | > difficult to port to platforms with different or no namespace | > implementations. A portable solution 9not to be confused with a | > portable implementation) would be preferable and without looking | > at details, I'd guess that you are going down the portable route, | > especially since you are not leaning on syntax... | | One non-portable part would be the ClassBuilder extensions! That lets | you plug a new class into an Environment. I'm not sure how you'd coax | an external compiler (Gemstone) into installing a new class into your | new, isolated, environment. | | frank | | > Dale | > | > ----- Original Message ----- | > | From: "Colin Putney" colin@wiresong.com | > | To: "Squeak-Dev developers list" | > | squeak-dev@lists.squeakfoundation.org | > | Sent: Monday, June 25, 2012 7:11:18 PM | > | Subject: [squeak-dev] Environments | > | | > | Hi all, | > | | > | There's an old joke in the Squeak community about how we have a | > | flame | > | war about namespaces every few years and only newbies bring up | > | the | > | topic casually. Well, it seems we're overdue, so I'd like to do | > | my | > | bit | > | for the community by keeping up the tradition. | > | | > | I propose that Squeak 4.4, or perhaps 4.5, include support for | > | more | > | than one class with the same name. This will be a modest | > | proposal, | > | based on extending Dan's work on environments. The basic idea is | > | this: | > | an Environment is an object that implements a policy for binding | > | names | > | to objects during compilation. | > | | > | This is in direct contrast to the Namespace implementation that | > | VisualWorks uses. In VW the global namespace is divided up into a | > | dot-delimited hierarchy, and there are mechanisms for resolving | > | unqualified names. Environments, in contrast, are more like | > | Newspeak | > | modules. There's no universal mapping of names to objects, but | > | rather | > | different "points of view," where names resolve differently | > | depending | > | on which environment you're in. | > | | > | The simplest and most common use for environments is to allow two | > | classes with the same name to peacefully co-exist. We currently | > | work | > | around this problem with classname prefixes - MC in Monticello or | > | WA | > | in Seaside. With environments, we can do away with prefixes by | > | creating a separate environment for each prefix that we're | > | currently | > | using. | > | | > | An interesting example of this case that I've run across lately | > | is | > | Xtreams. In the original VW version, there's only one class | > | that's | > | publicly visible: the Incomplete exception that gets raised when | > | a | > | stream operation fails. The rest of the public API to the library | > | is | > | provided as extensions to classes in the base system. There's | > | actually | > | no need for code that uses Xtreams to refer to any of the stream | > | classes. That leaves a lot of room for the implementation of | > | Xtreams | > | to change while keeping the API stable, and I'd like to be able | > | to | > | take advantage of this design in Squeak. With Environments, | > | that's | > | possible: we just create an environment to hold the Xtreams | > | classes, | > | import the base system, compile Xtreams, export Incomplete, and | > | import | > | Xtreams into our application's environment. | > | | > | I've done a preliminary implementation, which lets me create an | > | empty | > | environment, file code into it and then browse and modify it with | > | a | > | standard browser. There's still lots of work to do, but I want to | > | get | > | a consensus among the core developers before tackling it. That | > | way | > | the | > | changes can happen in the trunk and we don't have to worry about | > | a | > | difficult integration later. | > | | > | I've attached a couple of screenshots. The first shows two | > | browsers, | > | one browsing the base image, the other browsing an environment | > | with | > | Seaside 3.0 loaded. The second is an explorer on the Seaside | > | environment. The image where they were taken is available for | > | download | > | here: | > | | > | http://www.wiresong.ca/downloads/Environments.zip | > | | > | | > | Flame away! | > | | > | Colin | > | | > | | > | | > | |
On 26 June 2012 17:44, Dale Henrichs dhenrich@vmware.com wrote:
Frank,
As far as GemStone is concerned we've had separate environments for classes for a very long time. Instead of a Smalltalk dictionary, GemStone does global lookups using a list of dictionaries (SymbolList) and this list can be dynamically adjusted by the user. So in the end, I'd think that it would be straightforward to add this type of namespace to GemStone.
Ah, excellent! I'd imagined (in my ignorance) that since GemStone has the (to my mind) unusual C-based compiler, that it might have issues in this regard.
frank
We've also got dynamic lookups for methods as well ... it's what we've used make it possible to run Ruby in a Smalltalk environment and it's what we use in GLASS for the Squeak/Pharo compatibility later ... I haven't looked at what it would take to isolate the method look up to an environment (i.e., environment-specific extension methods to shared classes), but it's something that we'd eventually like to do.
Dale
----- Original Message ----- | From: "Frank Shearar" frank.shearar@gmail.com | To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org | Sent: Tuesday, June 26, 2012 9:30:28 AM | Subject: Re: [squeak-dev] Environments | | On 26 June 2012 17:26, Dale Henrichs dhenrich@vmware.com wrote: | > Colin, | > | > Be aware that code written to run in namespaces will be much more | > difficult to port to platforms with different or no namespace | > implementations. A portable solution 9not to be confused with a | > portable implementation) would be preferable and without looking | > at details, I'd guess that you are going down the portable route, | > especially since you are not leaning on syntax... | | One non-portable part would be the ClassBuilder extensions! That lets | you plug a new class into an Environment. I'm not sure how you'd coax | an external compiler (Gemstone) into installing a new class into your | new, isolated, environment. | | frank | | > Dale | > | > ----- Original Message ----- | > | From: "Colin Putney" colin@wiresong.com | > | To: "Squeak-Dev developers list" | > | squeak-dev@lists.squeakfoundation.org | > | Sent: Monday, June 25, 2012 7:11:18 PM | > | Subject: [squeak-dev] Environments | > | | > | Hi all, | > | | > | There's an old joke in the Squeak community about how we have a | > | flame | > | war about namespaces every few years and only newbies bring up | > | the | > | topic casually. Well, it seems we're overdue, so I'd like to do | > | my | > | bit | > | for the community by keeping up the tradition. | > | | > | I propose that Squeak 4.4, or perhaps 4.5, include support for | > | more | > | than one class with the same name. This will be a modest | > | proposal, | > | based on extending Dan's work on environments. The basic idea is | > | this: | > | an Environment is an object that implements a policy for binding | > | names | > | to objects during compilation. | > | | > | This is in direct contrast to the Namespace implementation that | > | VisualWorks uses. In VW the global namespace is divided up into a | > | dot-delimited hierarchy, and there are mechanisms for resolving | > | unqualified names. Environments, in contrast, are more like | > | Newspeak | > | modules. There's no universal mapping of names to objects, but | > | rather | > | different "points of view," where names resolve differently | > | depending | > | on which environment you're in. | > | | > | The simplest and most common use for environments is to allow two | > | classes with the same name to peacefully co-exist. We currently | > | work | > | around this problem with classname prefixes - MC in Monticello or | > | WA | > | in Seaside. With environments, we can do away with prefixes by | > | creating a separate environment for each prefix that we're | > | currently | > | using. | > | | > | An interesting example of this case that I've run across lately | > | is | > | Xtreams. In the original VW version, there's only one class | > | that's | > | publicly visible: the Incomplete exception that gets raised when | > | a | > | stream operation fails. The rest of the public API to the library | > | is | > | provided as extensions to classes in the base system. There's | > | actually | > | no need for code that uses Xtreams to refer to any of the stream | > | classes. That leaves a lot of room for the implementation of | > | Xtreams | > | to change while keeping the API stable, and I'd like to be able | > | to | > | take advantage of this design in Squeak. With Environments, | > | that's | > | possible: we just create an environment to hold the Xtreams | > | classes, | > | import the base system, compile Xtreams, export Incomplete, and | > | import | > | Xtreams into our application's environment. | > | | > | I've done a preliminary implementation, which lets me create an | > | empty | > | environment, file code into it and then browse and modify it with | > | a | > | standard browser. There's still lots of work to do, but I want to | > | get | > | a consensus among the core developers before tackling it. That | > | way | > | the | > | changes can happen in the trunk and we don't have to worry about | > | a | > | difficult integration later. | > | | > | I've attached a couple of screenshots. The first shows two | > | browsers, | > | one browsing the base image, the other browsing an environment | > | with | > | Seaside 3.0 loaded. The second is an explorer on the Seaside | > | environment. The image where they were taken is available for | > | download | > | here: | > | | > | http://www.wiresong.ca/downloads/Environments.zip | > | | > | | > | Flame away! | > | | > | Colin | > | | > | | > | | > | |
Frank,
You were right to make that assumption, since the C-based compiler often does get in the way:)
Dale
----- Original Message ----- | From: "Frank Shearar" frank.shearar@gmail.com | To: "The general-purpose Squeak developers list" squeak-dev@lists.squeakfoundation.org | Sent: Tuesday, June 26, 2012 9:47:12 AM | Subject: Re: [squeak-dev] Environments | | On 26 June 2012 17:44, Dale Henrichs dhenrich@vmware.com wrote: | > Frank, | > | > As far as GemStone is concerned we've had separate environments for | > classes for a very long time. Instead of a Smalltalk dictionary, | > GemStone does global lookups using a list of dictionaries | > (SymbolList) and this list can be dynamically adjusted by the | > user. So in the end, I'd think that it would be straightforward to | > add this type of namespace to GemStone. | | Ah, excellent! I'd imagined (in my ignorance) that since GemStone has | the (to my mind) unusual C-based compiler, that it might have issues | in this regard. | | frank | | > We've also got dynamic lookups for methods as well ... it's what | > we've used make it possible to run Ruby in a Smalltalk environment | > and it's what we use in GLASS for the Squeak/Pharo compatibility | > later ... I haven't looked at what it would take to isolate the | > method look up to an environment (i.e., environment-specific | > extension methods to shared classes), but it's something that we'd | > eventually like to do. | > | > Dale | > | > ----- Original Message ----- | > | From: "Frank Shearar" frank.shearar@gmail.com | > | To: "The general-purpose Squeak developers list" | > | squeak-dev@lists.squeakfoundation.org | > | Sent: Tuesday, June 26, 2012 9:30:28 AM | > | Subject: Re: [squeak-dev] Environments | > | | > | On 26 June 2012 17:26, Dale Henrichs dhenrich@vmware.com wrote: | > | > Colin, | > | > | > | > Be aware that code written to run in namespaces will be much | > | > more | > | > difficult to port to platforms with different or no namespace | > | > implementations. A portable solution 9not to be confused with a | > | > portable implementation) would be preferable and without | > | > looking | > | > at details, I'd guess that you are going down the portable | > | > route, | > | > especially since you are not leaning on syntax... | > | | > | One non-portable part would be the ClassBuilder extensions! That | > | lets | > | you plug a new class into an Environment. I'm not sure how you'd | > | coax | > | an external compiler (Gemstone) into installing a new class into | > | your | > | new, isolated, environment. | > | | > | frank | > | | > | > Dale | > | > | > | > ----- Original Message ----- | > | > | From: "Colin Putney" colin@wiresong.com | > | > | To: "Squeak-Dev developers list" | > | > | squeak-dev@lists.squeakfoundation.org | > | > | Sent: Monday, June 25, 2012 7:11:18 PM | > | > | Subject: [squeak-dev] Environments | > | > | | > | > | Hi all, | > | > | | > | > | There's an old joke in the Squeak community about how we have | > | > | a | > | > | flame | > | > | war about namespaces every few years and only newbies bring | > | > | up | > | > | the | > | > | topic casually. Well, it seems we're overdue, so I'd like to | > | > | do | > | > | my | > | > | bit | > | > | for the community by keeping up the tradition. | > | > | | > | > | I propose that Squeak 4.4, or perhaps 4.5, include support | > | > | for | > | > | more | > | > | than one class with the same name. This will be a modest | > | > | proposal, | > | > | based on extending Dan's work on environments. The basic idea | > | > | is | > | > | this: | > | > | an Environment is an object that implements a policy for | > | > | binding | > | > | names | > | > | to objects during compilation. | > | > | | > | > | This is in direct contrast to the Namespace implementation | > | > | that | > | > | VisualWorks uses. In VW the global namespace is divided up | > | > | into a | > | > | dot-delimited hierarchy, and there are mechanisms for | > | > | resolving | > | > | unqualified names. Environments, in contrast, are more like | > | > | Newspeak | > | > | modules. There's no universal mapping of names to objects, | > | > | but | > | > | rather | > | > | different "points of view," where names resolve differently | > | > | depending | > | > | on which environment you're in. | > | > | | > | > | The simplest and most common use for environments is to allow | > | > | two | > | > | classes with the same name to peacefully co-exist. We | > | > | currently | > | > | work | > | > | around this problem with classname prefixes - MC in | > | > | Monticello or | > | > | WA | > | > | in Seaside. With environments, we can do away with prefixes | > | > | by | > | > | creating a separate environment for each prefix that we're | > | > | currently | > | > | using. | > | > | | > | > | An interesting example of this case that I've run across | > | > | lately | > | > | is | > | > | Xtreams. In the original VW version, there's only one class | > | > | that's | > | > | publicly visible: the Incomplete exception that gets raised | > | > | when | > | > | a | > | > | stream operation fails. The rest of the public API to the | > | > | library | > | > | is | > | > | provided as extensions to classes in the base system. There's | > | > | actually | > | > | no need for code that uses Xtreams to refer to any of the | > | > | stream | > | > | classes. That leaves a lot of room for the implementation of | > | > | Xtreams | > | > | to change while keeping the API stable, and I'd like to be | > | > | able | > | > | to | > | > | take advantage of this design in Squeak. With Environments, | > | > | that's | > | > | possible: we just create an environment to hold the Xtreams | > | > | classes, | > | > | import the base system, compile Xtreams, export Incomplete, | > | > | and | > | > | import | > | > | Xtreams into our application's environment. | > | > | | > | > | I've done a preliminary implementation, which lets me create | > | > | an | > | > | empty | > | > | environment, file code into it and then browse and modify it | > | > | with | > | > | a | > | > | standard browser. There's still lots of work to do, but I | > | > | want to | > | > | get | > | > | a consensus among the core developers before tackling it. | > | > | That | > | > | way | > | > | the | > | > | changes can happen in the trunk and we don't have to worry | > | > | about | > | > | a | > | > | difficult integration later. | > | > | | > | > | I've attached a couple of screenshots. The first shows two | > | > | browsers, | > | > | one browsing the base image, the other browsing an | > | > | environment | > | > | with | > | > | Seaside 3.0 loaded. The second is an explorer on the Seaside | > | > | environment. The image where they were taken is available for | > | > | download | > | > | here: | > | > | | > | > | http://www.wiresong.ca/downloads/Environments.zip | > | > | | > | > | | > | > | Flame away! | > | > | | > | > | Colin | > | > | | > | > | | > | > | | > | > | > | | > | | > | |
On Tue, Jun 26, 2012 at 9:26 AM, Dale Henrichs dhenrich@vmware.com wrote:
Be aware that code written to run in namespaces will be much more difficult to port to platforms with different or no namespace implementations. A portable solution 9not to be confused with a portable implementation) would be preferable and without looking at details, I'd guess that you are going down the portable route, especially since you are not leaning on syntax...
Yes. Portability is important. I hope to end up with a solution where application/framework code just assumes a flat namespace, and only the tools need to be environment-aware. The only difference for application code should be that class-name prefixes are no longer necessary. Without having looked into it, I'd guess that porting such code to Gemstone, VisualWorks and GST would be pretty easy. I don't think VA has namespaces, (somebody correct me if I'm wrong) so that might be a bit trickier.
Colin
Hi Colin and all!
First of all - you are brave :)
Anyway, a few thoughts of mine, although I am no longer "invested" in this area, I was earlier but have given up waaaay back.
1. AFAICT this will (in contrary to my solution) remove the "modelessness" we have today. Or in other words, a code snippet will behave differently depending on which environment you are in. One can argue that this also holds true today (class variables shadowing globals for example) but still. It reminds me of VA for Java where you had to tell the "Workspace" in which class it was being run (in order to get all the imports right). I am not sure I like where this is leading. NOTE: My proposal meant that all class refs were actually in full, never short. They just "rendered" short when it was reasonable.
2. Reading code will force me to always be aware of which environments are imported into the package I am reading. Otherwise I will not know which class is referred to when I read "Manager". NOTE: My proposal would always expand names into full names if there were more than two in the image.
3. And finally, this is AFAICT the same "pessimistic" approach that Java etc use - in other words, each developer/project will create his/her own little sandbox (=environment) and will start creating duplicate names for things (knowingly or unknowingly) and will never really "notice" this because this solution will never make it apparent that it has been done. NOTE: My proposal would lead to ambiguous names being rendered with full path and also asking the developer if he meant Color::Orange of Fruit::Orange whenever he tried to type just "Orange" - thus making him (and all others) aware of the slightly unfortunate name clash.
I am merely contrasting this with my own proposal from years back in order to hear people's views on the above aspects.
Personally I am *happy* that this stone is finally turned.
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
regards, Göran
On 27.06.2012, at 10:35, Göran Krampe wrote:
Personally I am *happy* that this stone is finally turned.
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
regards, Göran
It just means that Squeak is a happier and friendlier place now.
Taking tension out of the community was the only good outcome of the fork.
- Bert -
Hey!
On 06/27/2012 11:29 AM, Bert Freudenberg wrote:
On 27.06.2012, at 10:35, Göran Krampe wrote:
Personally I am *happy* that this stone is finally turned.
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
regards, Göran
It just means that Squeak is a happier and friendlier place now.
Taking tension out of the community was the only good outcome of the fork.
Sure, but if it means we are slowly starving to death, it doesn't matter how friendly it is. ;)
Anyway, at this point I applaud ANY initiatives, so go Colin, go.
regards, Göran
On 27.06.2012, at 11:53, Göran Krampe wrote:
Hey!
On 06/27/2012 11:29 AM, Bert Freudenberg wrote:
On 27.06.2012, at 10:35, Göran Krampe wrote:
Personally I am *happy* that this stone is finally turned.
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
regards, Göran
It just means that Squeak is a happier and friendlier place now.
Taking tension out of the community was the only good outcome of the fork.
Sure, but if it means we are slowly starving to death, it doesn't matter how friendly it is. ;)
Being not as loud as others is hardly the same as starving. And being friendly does matter a lot. To us anyway ;)
- Bert -
On 06/27/2012 12:10 PM, Bert Freudenberg wrote:
On 27.06.2012, at 11:53, Göran Krampe wrote:
Hey!
On 06/27/2012 11:29 AM, Bert Freudenberg wrote:
On 27.06.2012, at 10:35, Göran Krampe wrote:
Personally I am *happy* that this stone is finally turned.
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
regards, Göran
It just means that Squeak is a happier and friendlier place now.
Taking tension out of the community was the only good outcome of the fork.
Sure, but if it means we are slowly starving to death, it doesn't matter how friendly it is. ;)
Being not as loud as others is hardly the same as starving. And being friendly does matter a lot. To us anyway ;)
I definitely agree with the friendly part. That is something I have always been proud of - the friendliness of our community.
Nevertheless I am still worried that Squeak.org is being starved. It would be interesting to hear views/ideas from the board (and others) on this, and possible ways to adapt to it.
Earlier Seaside and web development has been a "driver" behind the community - the fact that if you build web apps, it doesn't matter how the backend "looks" (thus the UI of Squeak was of no importance).
These days I am unsure of Squeak's "place" in the world.
regards, Göran
A few minute ago , Göran Krampe wrote:
These days I am unsure of Squeak's "place" in the world.
I think this deserves personal answers. No two Squeakers have the same world. For me Squeak occupies two important places:
(1) Home of Etoys (I hope one day that Etoys will be able to move to a version 4.x Squeak, if it hasn't already.)
(2) Home of an amazing and unique VM. (Pharo doesn't have a VM.)
There other things that count, such as being the platform for FONC/STEPS at VPRI, and being an integrated image, rather than a modular one whose source code is harder to search (my unpopular opinion which I voiced before.)
To all: where is Squeak in your world?
David
dcorking wrote
To all: where is Squeak in your world?
It's my personal computing environment that I use for experiments and enlightenment.
What I love most (in order of priority): 1. Hitting the "update button" :-) 2. Writing a five-liner to do something Really Hard (tm). 3. Reading discussions on Squeak-dev.
Cheers, - Andreas
-- View this message in context: http://forum.world.st/Environments-tp4636629p4636887.html Sent from the Squeak - Dev mailing list archive at Nabble.com.
On Wed, Jun 27, 2012 at 12:09:23PM +0100, David Corking wrote:
A few minute ago , G?ran Krampe wrote:
These days I am unsure of Squeak's "place" in the world.
To all: where is Squeak in your world?
I like spending time with Squeak, and I appreciate that it is different in ways that attract creative, intelligent people who don't necessarily pay attention to what other people think is the the latest cool thing.
I spend a good deal of my personal free time with Squeak because I enjoy it, I learn from it, and I like being part of the community.
Dave
I don't code my projects in squeak , because I don't really like smalltalk syntax as much I love python. But I do like to play around with squeak and pharo and copy all their cool ideas to python. Right now I am making a project that has the ambition to sort of (emphasis on "sort of") port squeak to python.
I started with porting Morphic , to my GUI which I call Morpheas. Its not a copy from the code side , though there are still a lot of similarities , but more like a copy at the user side, of all the super cool functionally that we have come to love in Morphic and with several other enhancements that I plan for it. My project is named "Ephestos" and you can find it here -> https://github.com/kilon/Ephestos
I have announced it here , and even had a squeak source page for it because I first intended to make it for squeak, but it was also my intention to integrate it to Blender. Also I knew that multicore functionality and threads would be kinda cool , include to that the not so great squeak documentation, buggy libraries and lack of them, choosing python was the easy option of course once again Blender supporting python played a huger role to my decision too. But squeak is not completely out of the window as option. Part of my project is to provide a bridge between languages so it makes possible to use Ephestos with all languages. At the moment my bridge works cross blender python, cpython 3 , cpython 2 and pypy. But because its XMLRPC and sockets it should work relatively easily for squeak too. Using that bridge its possible with no extra magic to call directly all Ephestos (and even blender's) functions . My code is 100% pure python so its easy to read even for those that don't know python at all.
Of course there is tons of stuff we need to implement to Ephestos and is nowhere near to squeak at the moment. But at the good side, Blender users through Ephestos and Morpheas learn what Morphic is all about so you may have some more newcomers coming from my side and I would certainly recommend and support squeak, because its awesome. I have already introduced many people to it.
I don't think squeak will ever die , its too cool for that, but even if it did, through projects like mine that are intended for other language will live forever, because a great idea is copied a million times and is never lost.
I also agree the community of squeak and pharo is very nice, polite and helpful , probably the second best in my experience after the blender community.
________________________________ From: David T. Lewis lewis@mail.msen.com To: The general-purpose Squeak developers list squeak-dev@lists.squeakfoundation.org Sent: Wednesday, 27 June 2012, 17:17 Subject: Re: Squeak.org starving... and what to do about it - if so. (was Re: [squeak-dev] Environments)
On Wed, Jun 27, 2012 at 12:09:23PM +0100, David Corking wrote:
A few minute ago , G?ran Krampe wrote:
These days I am unsure of Squeak's "place" in the world.
To all: where is Squeak in your world?
I like spending time with Squeak, and I appreciate that it is different in ways that attract creative, intelligent people who don't necessarily pay attention to what other people think is the the latest cool thing.
I spend a good deal of my personal free time with Squeak because I enjoy it, I learn from it, and I like being part of the community.
Dave
Am 27.06.2012 13:09, schrieb David Corking:
To all: where is Squeak in your world? David
Squeak *is* important to me. it is in this order:
1- The environment I enjoy to work in. Part of it being Etoys-iness and Morphic.
2- The environment in which I develop the tools I need for my work (middleware, simulation, engineering).
3- Compared to Pharo: A stable and backwards compatible API protecting my (my customers) investment.
many more ...
- Herbert
Squeak's place in the world is as a platform for Aikido-style development concerned with real-world domains that require longevity. The current trunk platform represents the product of ~15 years of discussions, arguments, wrangling and sweat from an incredibly talented and diverse group of developers. I believe this community recognizes the value of its approach. As the trunk advances incrementally, the community moves forward together as a unit. Everyone benefits by everyone else's work because work from the past is respected, not belittled.
Squeak does not want to take over the world or be "hip". It's members are independent-minded and generally want to "get there" on their own and not told what to think.
On Wed, Jun 27, 2012 at 12:23 PM, Herbert König herbertkoenig@gmx.net wrote:
Am 27.06.2012 13:09, schrieb David Corking:
To all: where is Squeak in your world? David
Squeak *is* important to me. it is in this order:
1- The environment I enjoy to work in. Part of it being Etoys-iness and Morphic.
2- The environment in which I develop the tools I need for my work (middleware, simulation, engineering).
3- Compared to Pharo: A stable and backwards compatible API protecting my (my customers) investment.
many more ...
- Herbert
The idea of getting a lot out of a little. I'm not a student of it (yet), but I'm intrigued by the aspect of Aikido that "directs" the energy of the opposer rather than head-on resistance. Obviously this requires less power, like "Moving 100 pounds with 4 ounces" of T'ai Chi. For Squeak the opposer are the challenges that faced, the directing represents incremental advancement.
On Thu, Jun 28, 2012 at 3:14 PM, Stéphane Rollandin lecteur@zogotounga.net wrote:
Squeak's place in the world is as a platform for Aikido-style development
Interesting; could you elaborate on this metaphor ? (I'm studying Aikido myself :)
Stef
These days I am unsure of Squeak's "place" in the world.
It is the *only* development environment where I can do what I do (namely, muO).
Squeak may not be precious to many people, but precious it is nonetheless.
Stef
On Wed, Jun 27, 2012 at 3:50 AM, Göran Krampe goran@krampe.se wrote:
I definitely agree with the friendly part. That is something I have always been proud of - the friendliness of our community.
Nevertheless I am still worried that Squeak.org is being starved. It would be interesting to hear views/ideas from the board (and others) on this, and possible ways to adapt to it.
Well, there's no doubt that the community forked along with the code. There are a few people who contribute to both Pharo and Squeak, but not a lot. This leads to both communities being smaller, although you don't notice that with Pharo.
Earlier Seaside and web development has been a "driver" behind the community - the fact that if you build web apps, it doesn't matter how the backend "looks" (thus the UI of Squeak was of no importance).
Well, I'm still using Squeak for web development. Sure, most of the web dev crowd has moved to Pharo, but Squeak is still a good platform for the web.
These days I am unsure of Squeak's "place" in the world.
On of the effects of the fork has been to reduce the pressure on us, in the Squeak community, to make releases with big new features or invasive "cleaning". That, in turn has allowed us to focus on fundamentals that aren't flashy, but are important to advancing the platform. A lot of our work in the past couple of years has been around forging better links with other forks of Squeak, oddly enough.
Along with VRPI, we did the legwork to make the MIT relicensing happen. We merged in code from the Cuis, Teleplace, and Etoys forks, both to improve Squeak and to make it more compatible with those variants. Recently we've been working on fixing compatibility issues with the Scratch fork so that it can continue to work even though the new version of Scratch will be based on Flash.
One of the effects of our continued collaboration with the Etoys community has been to strengthen our ties with the wider world of open source. Many Linux distributions now include Squeak packages. Randall has been giving talks about Squeak in more "mainstream" fora dedicated to Linux and Perl.
So what's Squeak's place in the world? I'm not sure either, to tell the truth. It's changing, and the Pharo fork has had a lot to do with that. But I like the direction we're taking and a look forward to seeing where we end up.
Colin
On 6/27/12 6:29 AM, "Bert Freudenberg" bert@freudenbergs.de wrote:
On 27.06.2012, at 10:35, Göran Krampe wrote:
Personally I am *happy* that this stone is finally turned.
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
regards, Göran
It just means that Squeak is a happier and friendlier place now.
Taking tension out of the community was the only good outcome of the fork.
- Bert -
Los cementerios estan llenos de paz The cemeteries are full of peace
Edgar
On 27 June 2012 09:35, Göran Krampe goran@krampe.se wrote:
Hi Colin and all!
First of all - you are brave :)
Anyway, a few thoughts of mine, although I am no longer "invested" in this area, I was earlier but have given up waaaay back.
- AFAICT this will (in contrary to my solution) remove the "modelessness"
we have today. Or in other words, a code snippet will behave differently depending on which environment you are in. One can argue that this also holds true today (class variables shadowing globals for example) but still. It reminds me of VA for Java where you had to tell the "Workspace" in which class it was being run (in order to get all the imports right). I am not sure I like where this is leading. NOTE: My proposal meant that all class refs were actually in full, never short. They just "rendered" short when it was reasonable.
- Reading code will force me to always be aware of which environments are
imported into the package I am reading. Otherwise I will not know which class is referred to when I read "Manager". NOTE: My proposal would always expand names into full names if there were more than two in the image.
Which means tools might need adjusting. Hover over a class name and the browser tells you the local name and, if it's an import, where it came from and what its "real" name is.
(I'd love to have that kind of thing anyway, actually: in your Debugger, being able to hover over a variable to see its value would be marvelous. A topic for another day.)
- And finally, this is AFAICT the same "pessimistic" approach that Java etc
use - in other words, each developer/project will create his/her own little sandbox (=environment) and will start creating duplicate names for things (knowingly or unknowingly) and will never really "notice" this because this solution will never make it apparent that it has been done. NOTE: My proposal would lead to ambiguous names being rendered with full path and also asking the developer if he meant Color::Orange of Fruit::Orange whenever he tried to type just "Orange" - thus making him (and all others) aware of the slightly unfortunate name clash.
On the flip side it means I can safely compose two libraries that I'd really like to use together, but can't, because they use the same class names. And I can do that without rewriting source.
More importantly, Environment is a wedge. First you can load multiple classes with the same name. Then you can hide classes, protecting a library's internals (Environment does this already). Then you can selectively import those external classes you need (Environment does this already). Then you can _only_ import external references, and not just rely on some ambient knows-everything environment. And hey, you're suddenly forced into declaring your library's dependencies. That is _good_.
Controlling classes is the easy part, but one thing at a time.
frank
I am merely contrasting this with my own proposal from years back in order to hear people's views on the above aspects.
Personally I am *happy* that this stone is finally turned.
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
regards, Göran
Hey!
On 06/27/2012 03:46 PM, Frank Shearar wrote:
On 27 June 2012 09:35, Göran Krampe goran@krampe.se wrote:
Hi Colin and all!
First of all - you are brave :)
Anyway, a few thoughts of mine, although I am no longer "invested" in this area, I was earlier but have given up waaaay back.
- AFAICT this will (in contrary to my solution) remove the "modelessness"
we have today. Or in other words, a code snippet will behave differently depending on which environment you are in. One can argue that this also holds true today (class variables shadowing globals for example) but still. It reminds me of VA for Java where you had to tell the "Workspace" in which class it was being run (in order to get all the imports right). I am not sure I like where this is leading. NOTE: My proposal meant that all class refs were actually in full, never short. They just "rendered" short when it was reasonable.
- Reading code will force me to always be aware of which environments are
imported into the package I am reading. Otherwise I will not know which class is referred to when I read "Manager". NOTE: My proposal would always expand names into full names if there were more than two in the image.
Which means tools might need adjusting. Hover over a class name and the browser tells you the local name and, if it's an import, where it came from and what its "real" name is.
(I'd love to have that kind of thing anyway, actually: in your Debugger, being able to hover over a variable to see its value would be marvelous. A topic for another day.)
Agree on both accounts. Just trying to remind us that this will add a "mental hurdle" in reading code. Sure, tools can help - but only so much.
- And finally, this is AFAICT the same "pessimistic" approach that Java etc
use - in other words, each developer/project will create his/her own little sandbox (=environment) and will start creating duplicate names for things (knowingly or unknowingly) and will never really "notice" this because this solution will never make it apparent that it has been done. NOTE: My proposal would lead to ambiguous names being rendered with full path and also asking the developer if he meant Color::Orange of Fruit::Orange whenever he tried to type just "Orange" - thus making him (and all others) aware of the slightly unfortunate name clash.
On the flip side it means I can safely compose two libraries that I'd really like to use together, but can't, because they use the same class names. And I can do that without rewriting source.
In fact, my solution (sorry for referring to it - but I do it for "comparison", not trying to push it) allowed that too because *all* class references in source code were always *in full*.
In other words - it worked just like prefixes does today. You can easily combine Seaside (WA*) with Monticello (MC*) and no names will clash. In essence, my solution was "prefixing improved", so it worked exactly the same.
More importantly, Environment is a wedge. First you can load multiple classes with the same name. Then you can hide classes, protecting a library's internals (Environment does this already). Then you can selectively import those external classes you need (Environment does this already). Then you can _only_ import external references, and not just rely on some ambient knows-everything environment. And hey, you're suddenly forced into declaring your library's dependencies. That is _good_.
Personally I just feel complexity lurking in the shadows... I hope I am wrong. ;)
regards, Göran
On 27 June 2012 15:54, Göran Krampe goran@krampe.se wrote:
Hey!
On 06/27/2012 03:46 PM, Frank Shearar wrote:
On 27 June 2012 09:35, Göran Krampe goran@krampe.se wrote:
Hi Colin and all!
First of all - you are brave :)
Anyway, a few thoughts of mine, although I am no longer "invested" in this area, I was earlier but have given up waaaay back.
- AFAICT this will (in contrary to my solution) remove the
"modelessness" we have today. Or in other words, a code snippet will behave differently depending on which environment you are in. One can argue that this also holds true today (class variables shadowing globals for example) but still. It reminds me of VA for Java where you had to tell the "Workspace" in which class it was being run (in order to get all the imports right). I am not sure I like where this is leading. NOTE: My proposal meant that all class refs were actually in full, never short. They just "rendered" short when it was reasonable.
- Reading code will force me to always be aware of which environments
are imported into the package I am reading. Otherwise I will not know which class is referred to when I read "Manager". NOTE: My proposal would always expand names into full names if there were more than two in the image.
Which means tools might need adjusting. Hover over a class name and the browser tells you the local name and, if it's an import, where it came from and what its "real" name is.
(I'd love to have that kind of thing anyway, actually: in your Debugger, being able to hover over a variable to see its value would be marvelous. A topic for another day.)
Agree on both accounts. Just trying to remind us that this will add a "mental hurdle" in reading code. Sure, tools can help - but only so much.
- And finally, this is AFAICT the same "pessimistic" approach that Java
etc use - in other words, each developer/project will create his/her own little sandbox (=environment) and will start creating duplicate names for things (knowingly or unknowingly) and will never really "notice" this because this solution will never make it apparent that it has been done. NOTE: My proposal would lead to ambiguous names being rendered with full path and also asking the developer if he meant Color::Orange of Fruit::Orange whenever he tried to type just "Orange" - thus making him (and all others) aware of the slightly unfortunate name clash.
On the flip side it means I can safely compose two libraries that I'd really like to use together, but can't, because they use the same class names. And I can do that without rewriting source.
In fact, my solution (sorry for referring to it - but I do it for "comparison", not trying to push it) allowed that too because *all* class references in source code were always *in full*.
In other words - it worked just like prefixes does today. You can easily combine Seaside (WA*) with Monticello (MC*) and no names will clash. In essence, my solution was "prefixing improved", so it worked exactly the same.
It's not really implicit. Given two libraries with "Session", you'd import and _locally_ prefix as MaSession and WaSession. When you read the code, you'd see those names, note the prefix, and possibly check the Environment import list.
frank
More importantly, Environment is a wedge. First you can load multiple classes with the same name. Then you can hide classes, protecting a library's internals (Environment does this already). Then you can selectively import those external classes you need (Environment does this already). Then you can _only_ import external references, and not just rely on some ambient knows-everything environment. And hey, you're suddenly forced into declaring your library's dependencies. That is _good_.
Personally I just feel complexity lurking in the shadows... I hope I am wrong. ;)
It's more that complexity is right in the room and everyone covers their eyes, puts their fingers in their ears and goes "lalalala" at the top of their voices. Modularity is hard.
frank
regards, Göran
Hi Göran,
On Wed, Jun 27, 2012 at 1:35 AM, Göran Krampe goran@krampe.se wrote:
- AFAICT this will (in contrary to my solution) remove the "modelessness"
we have today. Or in other words, a code snippet will behave differently depending on which environment you are in. One can argue that this also holds true today (class variables shadowing globals for example) but still. It reminds me of VA for Java where you had to tell the "Workspace" in which class it was being run (in order to get all the imports right). I am not sure I like where this is leading. NOTE: My proposal meant that all class refs were actually in full, never short. They just "rendered" short when it was reasonable.
Yes, you're quite right. It's the main difference between this proposal and VW, GST, and Gemán's GSOC work. I think Gemstone might be the only similar implementation, although I'm not conversant with the subtleties of Gemstone.
To me, this is a feature, not a bug. By giving up the notion of a single, universal view of the system, we gain a degree of freedom that we didn't have before. If we write code that doesn't rely on knowing where to find the classes it depends on, we gain the ability to redefine those dependencies without altering the code.
- Reading code will force me to always be aware of which environments are
imported into the package I am reading. Otherwise I will not know which class is referred to when I read "Manager". NOTE: My proposal would always expand names into full names if there were more than two in the image.
Also true. But you could say the same thing about dynamic dispatch: you always have to be aware the class of the receiver, otherwise you won't know what method will be executed. We mitigate message ambiguity with dev tools (implementors, explain) and we can do the same with class references.
- And finally, this is AFAICT the same "pessimistic" approach that Java
etc use - in other words, each developer/project will create his/her own little sandbox (=environment) and will start creating duplicate names for things (knowingly or unknowingly) and will never really "notice" this because this solution will never make it apparent that it has been done. NOTE: My proposal would lead to ambiguous names being rendered with full path and also asking the developer if he meant Color::Orange of Fruit::Orange whenever he tried to type just "Orange" - thus making him (and all others) aware of the slightly unfortunate name clash.
In practice we tend to do this already. We just pick a prefix and rely on that to avoid name conflicts. And why not? We're long past the point where we can have a single, unmangled namespace for all the classes that might get loaded into a given image.
Thanks for the pushback, Göran. Insightful as always.
Colin
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
It's probably premature to say the idea won't face any opposition. Right now I think we're still trying to understand Colins proposal before we flame it. :) It was only proposed just the other day and the thread is already > 20 posts from 9 unique posters in a community of very busy members so... ;)
On Wed, Jun 27, 2012 at 02:21:03PM -0500, Chris Muller wrote:
On the other hand I am *unhappy* that you aren't facing any opposition because unfortunately it may just indicate that our community have shrunk considerably and people are instead flaming each other over on Pharo-dev. ;)
It's probably premature to say the idea won't face any opposition. Right now I think we're still trying to understand Colins proposal before we flame it. :) It was only proposed just the other day and the thread is already > 20 posts from 9 unique posters in a community of very busy members so... ;)
Well there's a fine kettle of fish for you. Someone attempts to light up a good flame war and it just degenerates into a slow stream of thoughtful commentary, constructive ideas, and high quality code contributions. What have we come to?
;)
Dave
Well there's a fine kettle of fish for you. Someone attempts to light up a good flame war and it just degenerates into a slow stream of thoughtful commentary, constructive ideas, and high quality code contributions. What have we come to?
You're all idiots anyway !
(is that a good start for a flame war ?)
STef
On Thu, Jun 28, 2012 at 12:39:15AM +0200, St?phane Rollandin wrote:
Well there's a fine kettle of fish for you. Someone attempts to light up a good flame war and it just degenerates into a slow stream of thoughtful commentary, constructive ideas, and high quality code contributions. What have we come to?
You're all idiots anyway !
(is that a good start for a flame war ?)
Nice try, but we still like you and value your input ;)
Back in the Usenet news era it would be You're all a bunch of fags going to hell. No, better: Oo programmers are ... as above. That was when AOL connected to the Internet. Now *those* were flame wars! On Jun 27, 2012 12:39 PM, "Stéphane Rollandin" lecteur@zogotounga.net wrote:
Well there's a fine kettle of fish for you. Someone attempts to light up
a good flame war and it just degenerates into a slow stream of thoughtful commentary, constructive ideas, and high quality code contributions. What have we come to?
You're all idiots anyway !
(is that a good start for a flame war ?)
STef
On 26 June 2012 03:11, Colin Putney colin@wiresong.com wrote:
Hi all,
There's an old joke in the Squeak community about how we have a flame war about namespaces every few years and only newbies bring up the topic casually. Well, it seems we're overdue, so I'd like to do my bit for the community by keeping up the tradition.
I propose that Squeak 4.4, or perhaps 4.5, include support for more than one class with the same name. This will be a modest proposal, based on extending Dan's work on environments. The basic idea is this: an Environment is an object that implements a policy for binding names to objects during compilation.
This is in direct contrast to the Namespace implementation that VisualWorks uses. In VW the global namespace is divided up into a dot-delimited hierarchy, and there are mechanisms for resolving unqualified names. Environments, in contrast, are more like Newspeak modules. There's no universal mapping of names to objects, but rather different "points of view," where names resolve differently depending on which environment you're in.
The simplest and most common use for environments is to allow two classes with the same name to peacefully co-exist. We currently work around this problem with classname prefixes - MC in Monticello or WA in Seaside. With environments, we can do away with prefixes by creating a separate environment for each prefix that we're currently using.
An interesting example of this case that I've run across lately is Xtreams. In the original VW version, there's only one class that's publicly visible: the Incomplete exception that gets raised when a stream operation fails. The rest of the public API to the library is provided as extensions to classes in the base system. There's actually no need for code that uses Xtreams to refer to any of the stream classes. That leaves a lot of room for the implementation of Xtreams to change while keeping the API stable, and I'd like to be able to take advantage of this design in Squeak. With Environments, that's possible: we just create an environment to hold the Xtreams classes, import the base system, compile Xtreams, export Incomplete, and import Xtreams into our application's environment.
I've done a preliminary implementation, which lets me create an empty environment, file code into it and then browse and modify it with a standard browser. There's still lots of work to do, but I want to get a consensus among the core developers before tackling it. That way the changes can happen in the trunk and we don't have to worry about a difficult integration later.
I've attached a couple of screenshots. The first shows two browsers, one browsing the base image, the other browsing an environment with Seaside 3.0 loaded. The second is an explorer on the Seaside environment. The image where they were taken is available for download here:
http://www.wiresong.ca/downloads/Environments.zip
Flame away!
One thing I didn't try when I looked at the above image was run the tests. They mostly fail because setUp uses "env := Environment new" instead of "env := Environment name: 'Some Name'" and so the lookup instvar isn't set. You probably already know this.
I'd like to run an experiment with Environments, actually: on binding access, lazily create a subclass of the thing accessed. Initially, that would mean that in an Environment called 'Foo' when you say "Object new" the Environment makes a FooObject in the global space and exposes it as Object to the contained code. When you load a package that contains extensions to Object, they actually appear in FooObject, meaning that code outside the Environment doesn't see the extensions.
This doesn't solve the problem of clashing extensions when you import two environments with a common extension, but it does mean that loaded code goes into a sandbox. The code being loaded could still "true become: false" but "Smalltalk at: #Object put: nil" would only affect the loaded code.
Is there a place where we can get our hands on Monticello packages? Or does Environments require some bootstrapping?
frank
On Wed, Jul 4, 2012 at 4:41 AM, Frank Shearar frank.shearar@gmail.com wrote:
One thing I didn't try when I looked at the above image was run the tests. They mostly fail because setUp uses "env := Environment new" instead of "env := Environment name: 'Some Name'" and so the lookup instvar isn't set. You probably already know this.
Well, I knew it was buggy… :-)
I'd like to run an experiment with Environments, actually: on binding access, lazily create a subclass of the thing accessed. Initially, that would mean that in an Environment called 'Foo' when you say "Object new" the Environment makes a FooObject in the global space and exposes it as Object to the contained code. When you load a package that contains extensions to Object, they actually appear in FooObject, meaning that code outside the Environment doesn't see the extensions.
This doesn't solve the problem of clashing extensions when you import two environments with a common extension, but it does mean that loaded code goes into a sandbox. The code being loaded could still "true become: false" but "Smalltalk at: #Object put: nil" would only affect the loaded code.
Interesting. I'm not sure if you'd actually have to create FooObject globally. It could call ClassBuilder directly, and bind the resulting class as Object. You might also have to create the alias FooOriginalObject (or something) so that the browse could display a sane class definition. (Otherwise you'd get 'Object subclass: #Object…')
Is there a place where we can get our hands on Monticello packages? Or does Environments require some bootstrapping?
Yeah, Environments requires bootstrapping, but I haven't figured out how to do it yet. The image I posted is the one I did my hacking in, and getting it to that state involved frequent saving and lots of restarts. It's just a proof of concept.
That said, the MC packages are here: http://source.wiresong.ca/seed/
Colin
On 5 July 2012 00:28, Colin Putney colin@wiresong.com wrote:
On Wed, Jul 4, 2012 at 4:41 AM, Frank Shearar frank.shearar@gmail.com wrote:
One thing I didn't try when I looked at the above image was run the tests. They mostly fail because setUp uses "env := Environment new" instead of "env := Environment name: 'Some Name'" and so the lookup instvar isn't set. You probably already know this.
Well, I knew it was buggy… :-)
I'd like to run an experiment with Environments, actually: on binding access, lazily create a subclass of the thing accessed. Initially, that would mean that in an Environment called 'Foo' when you say "Object new" the Environment makes a FooObject in the global space and exposes it as Object to the contained code. When you load a package that contains extensions to Object, they actually appear in FooObject, meaning that code outside the Environment doesn't see the extensions.
This doesn't solve the problem of clashing extensions when you import two environments with a common extension, but it does mean that loaded code goes into a sandbox. The code being loaded could still "true become: false" but "Smalltalk at: #Object put: nil" would only affect the loaded code.
Interesting. I'm not sure if you'd actually have to create FooObject globally. It could call ClassBuilder directly, and bind the resulting class as Object. You might also have to create the alias FooOriginalObject (or something) so that the browse could display a sane class definition. (Otherwise you'd get 'Object subclass: #Object…')
Oh, definitely! Right _now_ ClassBuilder uses the SystemChangeNotifier to announce the birth of a new class. If you do the naive thing (as I describe above), even if you try add the new class to your own SystemDictionary, you end up with a reference in Smalltalk globals. That has... interesting effects. That's why I suggest a FooObject _for now_ because while it spams Smalltalk globals, it does so in a reasonably safe manner. Then we can make SystemChangeNotifier work per environment, and THEN we can stop making FooObjects.
Is there a place where we can get our hands on Monticello packages? Or does Environments require some bootstrapping?
Yeah, Environments requires bootstrapping, but I haven't figured out how to do it yet. The image I posted is the one I did my hacking in, and getting it to that state involved frequent saving and lots of restarts. It's just a proof of concept.
Mm, it's a proof of concept on which I want to hack :)
That said, the MC packages are here: http://source.wiresong.ca/seed/
Thanks!
frank
Colin
On Wed, 4 Jul 2012, Frank Shearar wrote:
snip
I'd like to run an experiment with Environments, actually: on binding access, lazily create a subclass of the thing accessed. Initially, that would mean that in an Environment called 'Foo' when you say "Object new" the Environment makes a FooObject in the global space and exposes it as Object to the contained code. When you load a package that contains extensions to Object, they actually appear in FooObject, meaning that code outside the Environment doesn't see the extensions.
This wouldn't work, because if you add an extension method to Object, then you have to create a copy of all classes of the global environment which are accessed from your environment (plus their superclasses up to Object). But in practice this doesn't work, because the VM has some expectations about some objects/classes (true, false, nil, LargePositiveInteger, etc). Also you'd have to convert objects which are passed from one environment to another, otherwise code like
foo class == bar class
would break.
Levente
This doesn't solve the problem of clashing extensions when you import two environments with a common extension, but it does mean that loaded code goes into a sandbox. The code being loaded could still "true become: false" but "Smalltalk at: #Object put: nil" would only affect the loaded code.
Is there a place where we can get our hands on Monticello packages? Or does Environments require some bootstrapping?
frank
On 5 July 2012 10:30, Levente Uzonyi leves@elte.hu wrote:
On Wed, 4 Jul 2012, Frank Shearar wrote:
snip
I'd like to run an experiment with Environments, actually: on binding access, lazily create a subclass of the thing accessed. Initially, that would mean that in an Environment called 'Foo' when you say "Object new" the Environment makes a FooObject in the global space and exposes it as Object to the contained code. When you load a package that contains extensions to Object, they actually appear in FooObject, meaning that code outside the Environment doesn't see the extensions.
This wouldn't work, because if you add an extension method to Object, then you have to create a copy of all classes of the global environment which are accessed from your environment (plus their superclasses up to Object).
In which you just lazily create those, even though my naive idea's now a lot more expensive. You almost might as well just spawn a new image.
But in practice this doesn't work, because the VM has some expectations about some objects/classes (true, false, nil, LargePositiveInteger, etc).
Right. So what you're saying is that if you want proper modules, you need VM support.
Also you'd have to convert objects which are passed from one environment to another, otherwise code like
foo class == bar class
would break.
How would you pass objects between environments? What does it mean to pass objects between environments?
frank
Levente
This doesn't solve the problem of clashing extensions when you import two environments with a common extension, but it does mean that loaded code goes into a sandbox. The code being loaded could still "true become: false" but "Smalltalk at: #Object put: nil" would only affect the loaded code.
Is there a place where we can get our hands on Monticello packages? Or does Environments require some bootstrapping?
frank
On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar frank.shearar@gmail.com wrote:
Right. So what you're saying is that if you want proper modules, you need VM support.
Not necessarily. For the next experiment, I've been thinking about implementing selector spaces. Here's how it might work:
• Each environment has its own Symbol table • The scanner delegates interning of symbols to the environment • When interning a symbol the environment searches its imports • If no imported environment has the symbol, it creates one in its own symbol table
This would mean that an environment could add extension methods to classes in other environments, without colliding with other extensions. It would also make it possible to create "private overrides" where only code in that environment would use the override. It might be useful for sandboxing, but might not be sufficient.
I want to stress, though, that this is *not* part of the current proposal—it's just some ruminating about what the next experiment might be, someday.
Colin
On 5 July 2012 18:15, Colin Putney colin@wiresong.com wrote:
On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar frank.shearar@gmail.com wrote:
Right. So what you're saying is that if you want proper modules, you need VM support.
Not necessarily. For the next experiment, I've been thinking about implementing selector spaces. Here's how it might work:
• Each environment has its own Symbol table • The scanner delegates interning of symbols to the environment • When interning a symbol the environment searches its imports • If no imported environment has the symbol, it creates one in its own symbol table
Does that mean that given libraries Foo and Bar that both define Object >> #thing, you provide some conflict resolution (say, {#thing1 -> (Foo at: #Object) >> #thing.}), and then in your Environment you have some method
doIt
This would mean that an environment could add extension methods to classes in other environments, without colliding with other extensions. It would also make it possible to create "private overrides" where only code in that environment would use the override. It might be useful for sandboxing, but might not be sufficient.
I want to stress, though, that this is *not* part of the current proposal—it's just some ruminating about what the next experiment might be, someday.
And while I'm drooling about the idea of a modular Squeak environment, what can I/we do to help this first stage?
Colin
Sigh. Send accident there.
On 5 July 2012 20:41, Frank Shearar frank.shearar@gmail.com wrote:
On 5 July 2012 18:15, Colin Putney colin@wiresong.com wrote:
On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar frank.shearar@gmail.com wrote:
Right. So what you're saying is that if you want proper modules, you need VM support.
Not necessarily. For the next experiment, I've been thinking about implementing selector spaces. Here's how it might work:
• Each environment has its own Symbol table • The scanner delegates interning of symbols to the environment • When interning a symbol the environment searches its imports • If no imported environment has the symbol, it creates one in its own symbol table
Does that mean that given libraries Foo and Bar that both define Object >> #thing, you provide some conflict resolution (say, {#thing1 -> (Foo at: #Object) >> #thing.}), and then in your Environment you have some method
doIt
doIt ^ self thing1
that the scanner turns that into a #thing sent to Foo's Object?
frank
This would mean that an environment could add extension methods to classes in other environments, without colliding with other extensions. It would also make it possible to create "private overrides" where only code in that environment would use the override. It might be useful for sandboxing, but might not be sufficient.
I want to stress, though, that this is *not* part of the current proposal—it's just some ruminating about what the next experiment might be, someday.
And while I'm drooling about the idea of a modular Squeak environment, what can I/we do to help this first stage?
Colin
On Thu, Jul 5, 2012 at 12:41 PM, Frank Shearar frank.shearar@gmail.com wrote:
Does that mean that given libraries Foo and Bar that both define Object >> #thing, you provide some conflict resolution (say, {#thing1 -> (Foo at: #Object) >> #thing.}), and then in your Environment you have some method
doIt ^ self thing1
Something like that. You'd do some kind of aliasing, like with globals, but I don't think you'd specify how #thing1 would resolve to a compiled method (that would prevent dynamic message dispatch). Instead you might so something like {#thing1 -> #Foo}. Then the scanner would find Foo's version of #thing when it encountered #thing1. That would make decompilation show #thing instead of #thing1. Or you could do something exotic with name mangling and ObjectsAsMethods, or... well, this is why I don't want to get into it yet. :-)
And while I'm drooling about the idea of a modular Squeak environment, what can I/we do to help this first stage?
I think the first stage is to introduce Environment, and install an instance as "Smalltalk globals" instead of a SystemDictionary.
Colin
On 2012-07-05, at 19:15, Colin Putney wrote:
On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar frank.shearar@gmail.com wrote:
Right. So what you're saying is that if you want proper modules, you need VM support.
Not necessarily. For the next experiment, I've been thinking about implementing selector spaces. Here's how it might work:
• Each environment has its own Symbol table • The scanner delegates interning of symbols to the environment • When interning a symbol the environment searches its imports • If no imported environment has the symbol, it creates one in its own symbol table
This would mean that an environment could add extension methods to classes in other environments, without colliding with other extensions. It would also make it possible to create "private overrides" where only code in that environment would use the override. It might be useful for sandboxing, but might not be sufficient.
Cool idea. Since the VM just cares about the identity of Symbols, we can have the same selector twice in one method dictionary. Each environment would send only the one from its own Symbol table.
I want to stress, though, that this is *not* part of the current proposal—it's just some ruminating about what the next experiment might be, someday.
Yep.
- Bert -
On Thu, Jul 5, 2012 at 1:27 PM, Bert Freudenberg bert@freudenbergs.dewrote:
On 2012-07-05, at 19:15, Colin Putney wrote:
On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar frank.shearar@gmail.com
wrote:
Right. So what you're saying is that if you want proper modules, you need VM support.
Not necessarily. For the next experiment, I've been thinking about implementing selector spaces. Here's how it might work:
• Each environment has its own Symbol table • The scanner delegates interning of symbols to the environment • When interning a symbol the environment searches its imports • If no imported environment has the symbol, it creates one in its own symbol table
This would mean that an environment could add extension methods to classes in other environments, without colliding with other extensions. It would also make it possible to create "private overrides" where only code in that environment would use the override. It might be useful for sandboxing, but might not be sufficient.
Cool idea. Since the VM just cares about the identity of Symbols, we can have the same selector twice in one method dictionary. Each environment would send only the one from its own Symbol table.
IIRC the implementation of Selector (might be Symbol?) in David Simmons' AOS and S# systems is effectively two-level. A Selector is on object with two inst vars, one being its defining environment and the other being the selector's unique string (Symbol?). The latter is what we think of as a Symbol right now, so any two Selector (Symbol?) objects with the same sequence of characters have the same underlying unique string (Symbol?). Selectors are the keys in method dictionaries and the message selectors in compiled methods (and presumably are used in superclass names, but here I'm not familiar enough). David had some complex mechanism whereby selectors could match based on having the same underlying character sequence and choosing the shortest distances between their environments. This sounds complex, but the idea of boxing a Symbol so that there's a reference to its environment looks to me to be a useful one.
One could imagine using only boxed selectors for messages defined in a particular environment. This makes introspecting easy. A Symbol's environment would be the root environment; a Selector's would be e.g. that of its environment inst var.
Note that the VM doesn't (and shouldn't) care what objects are used for selectors; SmallIntegers can be used e.g. to save space.
Just 2¢
I want to stress, though, that this is *not* part of the current proposal—it's just some ruminating about what the next experiment might be, someday.
Yep.
- Bert -
squeak-dev@lists.squeakfoundation.org