Environments

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

Re: Environments

Göran Krampe
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

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Colin Putney-3
In reply to this post by cbc
On Thu, Jun 28, 2012 at 9:48 PM, Chris Cunningham
<[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Environments

michal-list
In reply to this post by cbc

> the code wouldn't know which one to use

the code would always know which one to use: using the original 'bare'
name always resolves to the local (or unique) instance, using the
'alias' is guaranteed by the system to be unambiguous.


Reply | Threaded
Open this post in threaded view
|

Re: Environments

Bert Freudenberg
In reply to this post by Colin Putney-3
On 29.06.2012, at 08:57, Colin Putney wrote:

> On Thu, Jun 28, 2012 at 9:48 PM, Chris Cunningham
> <[hidden email]> 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.

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 -



Reply | Threaded
Open this post in threaded view
|

Re: Environments

Andreas.Raab
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
Reply | Threaded
Open this post in threaded view
|

Re: Environments

Colin Putney-3
In reply to this post by Bert Freudenberg
On Fri, Jun 29, 2012 at 3:32 AM, Bert Freudenberg <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Bert Freudenberg

On 29.06.2012, at 16:40, Colin Putney wrote:

> On Fri, Jun 29, 2012 at 3:32 AM, Bert Freudenberg <[hidden email]> 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




Reply | Threaded
Open this post in threaded view
|

Re: Environments

Colin Putney-3
On Fri, Jun 29, 2012 at 7:47 AM, Bert Freudenberg <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Frank Shearar-3
In reply to this post by Colin Putney-3
On 26 June 2012 03:11, Colin Putney <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Gary Dunn-2
In reply to this post by Stéphane Rollandin

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" <[hidden email]> 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



Reply | Threaded
Open this post in threaded view
|

Re: Environments

Colin Putney-3
In reply to this post by Frank Shearar-3
On Wed, Jul 4, 2012 at 4:41 AM, Frank Shearar <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Frank Shearar-3
On 5 July 2012 00:28, Colin Putney <[hidden email]> wrote:

> On Wed, Jul 4, 2012 at 4:41 AM, Frank Shearar <[hidden email]> 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
>

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Levente Uzonyi-2
In reply to this post by Frank Shearar-3
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
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Frank Shearar-3
On 5 July 2012 10:30, Levente Uzonyi <[hidden email]> 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
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Colin Putney-3
On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Frank Shearar-3
On 5 July 2012 18:15, Colin Putney <[hidden email]> wrote:

> On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar <[hidden email]> 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
>

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Frank Shearar-3
Sigh. Send accident there.

On 5 July 2012 20:41, Frank Shearar <[hidden email]> wrote:

> On 5 July 2012 18:15, Colin Putney <[hidden email]> wrote:
>> On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar <[hidden email]> 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
>>

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Colin Putney-3
In reply to this post by Frank Shearar-3
On Thu, Jul 5, 2012 at 12:41 PM, Frank Shearar <[hidden email]> 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

Reply | Threaded
Open this post in threaded view
|

Re: Environments

Bert Freudenberg
In reply to this post by Colin Putney-3

On 2012-07-05, at 19:15, Colin Putney wrote:

> On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar <[hidden email]> 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 -



Reply | Threaded
Open this post in threaded view
|

Re: Environments

Eliot Miranda-2


On Thu, Jul 5, 2012 at 1:27 PM, Bert Freudenberg <[hidden email]> wrote:

On 2012-07-05, at 19:15, Colin Putney wrote:

> On Thu, Jul 5, 2012 at 8:11 AM, Frank Shearar <[hidden email]> 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 -






--
best,
Eliot



123