Dynamic scoping (was: Proposal: Squeak-E = Squeak x Kernel-E)
spair at acm.org
Mon Jan 27 22:53:48 UTC 2003
> > What is not clear about those semantics? Since the
> transcript output
> > occurs before setting the value, the correct output is:
> > 0
> > 0
> Well, unclear in that there's a conflict between what I think
> the correct semantics should be (which we agree about), and
> the way in which it's likely to be implemented ;). In other
> words: take that example as a test case, and make sure it
> passes; it will probably force you into implementation
> strategies you wouldn't otherwise use.
Like not using the context stack for example? It's trivial to get
Continuation to do the correct thing with RuntimeEnvironments (as they
are currently implemented). When you create the continuation, you just
need to tell the saved environment to beShared. Subsequent modification
of the environment will then be isolated.
> > Originally, I wanted the ability set a value for all subsequent
> > operations that occur in a process...however, to accomplish
> that *and*
> > use the stack for maintaining scope enclosures would be quite
> > convoluted (if at all possible).
> I need the same thing, and yes, it's pretty near impossible
> (short of inserting dummy contexts at the root of the stack).
> For that kind of state, I do keep a separate, Process-keyed
> tree, and the interface looks like
> s := StateHolder new.
> s contents: 'foo'.
> [self assert: s contents isNil] fork.
> self assert: s contents = 'foo'.
> I won't show it here, but the nice part is that you can
> cheaply snapshot and restore the current value of all
> StateHolders in the Process at once - which is necessary for
> web-browser backtracking.
So remind me again why it's desirable to reuse the context stack for
runtime environments (and ultimately exceptions for that matter)? I'm
starting to doubt that it is. Yes, there are some things which are
simplified...but I think I might be squeezing myself into a straight
jacket because it happens to feel warm and cuddly.
It might however be much cleaner to put the environment pointer in
ContextPart rather than in Process (since Process is really just holding
onto the environment for the active context). But if I go that route,
I'll be fighting with the VM.
> It may be worthwhile to release Continuation, DynamicContext,
> and StateHolder together as a kind of "obscure control flow"
> package (along with my implementation of McCarthy's "amb",
> which is trippier than any of them). They're also the litmus
> test for Seaside portability - if you can get all of their
> tests passing in a particular dialect, porting Seaside will be a snap.
I'll have to read up an "amb"...but trippy should not be goal. ;)
BTW, the fact that continuations re-use processes threw me for a loop at
first. When I was doing the stuff for Swiki.net, I didn't re-use
processes, I just created new ones...it seemed a lot easier to follow
the control flow.
For example, when you evaluate a continuation, why not have the
continuation happen in a separate process? I about twisted my brain in
a knot when I tried to figure out how it worked to call a continuation
from the UIProcess (which I didn't think would work)...that is until I
realized that it in fact didn't work. It only fooled me into thinking
that it worked because the continuation was originally created from the
UIProcess. If you create a continuation in a workspace from within a
forked block and then later open an inspector on that continuation and
send it the #value message, you'll hose your UIProcess. That's a
devilish trick to pull on an unsuspecting victim. ;)
I've been thinking of ways to clean up Continuation a bit such that it
eliminates such freakish behavior. I think this might have the
pleasurable side effect of making Seaside's use of continuations a bit
easier to follow.
More information about the Squeak-dev