links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
Environments update March 2013
Last updated at 11:02 am UTC on 24 September 2016
Colin Putney
AttachmentSat, Mar 2, 2013 at 9:25 AM
Reply-To: The general-purpose Squeak developers list
To: Squeak-Dev developers list
Reply | Reply to all | Forward | Print | Delete | Show original
Hi all,

So I've been plugging away at Environments, and have a new implementation that supports renaming, but I wanted to get some feedback before figuring out the sequence of commits necessary to update the trunk safely.

The idea is to support this kind of scenario:

    seaside := (Environment named: #Seaside)
      import: Smalltalk globals;

    magma := (Environment named: #Magma)
      import: Smalltalk globals;

    app := (Environment named: #AwesomeApp)
      import: Smalltalk globals;
      import: seaside;
      from: seaside import: {#Session -> #SeasideSession};
      import: magma;
      from: magma import: {#Session -> #MagmaSession};

In order to have the decompiled code use the correct names, I've changed the way lookup works. Instead of moving bindings from one environment to another, we now create a separate set of bindings for each environment, and copy the values (i.e., classes and globals) into a new binding when a binding is imported.

I had originally thought to use something like #changed:/#update: to keep all the bindings in sync, but then I realized that ClassBuilder does a #becomeForward: updates a class. So it's really only globals that could become out of sync between environments. Since we have very few globals in the image, and they basically never change, an update mechanism may not be necessary in practice.

So, here are some possible ways to proceed:

1. Use #changed:/#update: or something similar to keep keep global variables in sync.

2. Idea from Eliot—adopt the same convention as VW, and send #value to the binding on every access. Then we could have a special Alias bindings that forward the #value message to the original binding.

3. Share bindings for global variables between environments and disallow renaming of globals.

4. Special case the traditional globals such as Transcript and Display, and disallow the creation of new globals.

Anyhow, I'd appreciate a code review from anybody who's interested in this stuff. To take a look, file the attached (hand edited) change set into an updated trunk image.




What does



A newly created environment has no imports and no exports. If you compile a method (or doIt) in such an environment, all bindings will be undeclared, and if you import it into another environment, none of its binding will be visible.

To be able to resolve bindings inside the environment, you need imports. #importSelf tells the environment to import its own contents, to make classes and globals defined in the environment visible to methods compiled in the environment. #exportSelf tells it to make all its contents visible to the outside world.

Continue reading with:
Notes about Environments September 2016 (A)