[Squeak-e] Are Handlers Dynamically Scoped? (was: Comments
on Lex's "Object as Capabilities in Squeak")
Mark S. Miller
markm at caplet.com
Sun Feb 2 13:48:32 CET 2003
At 12:28 PM 2/2/2003 Sunday, Allen Wirfs-Brock wrote:
>The primary technical difference between Smalltalk exceptions and Java/C++
>style exceptions is the sequencing of unwinding the stack and execution of
> the "handler block". As your know, in the Java model, the stack is
>unwound and then the handler block is executed. In the Smalltalk model the
>handler is executed before the stack is unwound. This allows resumable
>handles to be trivially implemented.
Does it have any other virtue? If we didn't have resumable handlers, would
there be any remaining reason to prefer this? Note that the issue isn't when
they're executed, but when they're looked up. Of course, they can't be
executed until they're looked up.
>I'm relatively confident that your CPS model could be extended to
>accommodate the Smalltalk exception model although it might be some work
>to do so.
The only way I can imagine reveals that this semantics is indeed a case of
dynamic scoping. The way I imagine:
A continuation could have an additional method available,
"getHandler: exceptionTypeOrSomething" that either already knows a handler
for that exceptionTypeOrSomething, or asks its continuation. This
non-destructive looking up the stack is simply a deeply bound implementation
model of dynamic scoping. (Alternatively, the continuation could instead have
a non-destructive "handle: exception" method which gets delegated back, but
it amounts to the same thing.)
The key thing about the Java alternative, unwinding to the handler, is that
the continuation is only ever invoked destructively, and is otherwise
opaque. So by the time the handler is invoked, it's a handler associated
with the immediate continuation, and not one retrieved from further back on
So even without resumption, if earlier handlers get invoked before later
unwind blocks, then I'd agree with Anthony that Smalltalk's exceptions are
an instance of dynamic scoping. This isn't to say that it's a bad idea. But
it does leave us with the following hypotheses:
1) Resumable handlers are bad.
2) Dynamically scoped resumable handlers (as in Smalltalk) are good, leaving
us with at least one case where dynamic scoping is a good idea. If it's a
good idea here, there are probably other cases as well.
3) Resumable handlers are good, but a resumable handler shouldn't be looked
up by dynamic scoping. (Note: Joule has lexical resumable handlers called
4) Terminating handler lookup should happen during unwind, like Java.
5) Terminating handler lookup should happen prior to unwind, as in
Smalltalk, making this handler lookup arguable another case of dynamic scoping.
(In order to make this point separate from #2, let's say "should" even in
the absence of the need to support #2.)
6) Terminating handler lookup should happen prior to unwind, but not by
looking up the stack. (Presumably, the alternative would be lexical. I know
of no systems that do this.)
Smalltalk: #2, #5.
Java & E: #1, #4.
Joule: #3. (Joule has no stack, and so can't have any conventional notion of
Does this seem like a useful framework for exploring the issue?
What are some arguments for #2 or #5? I'm prepared to argue for #1, #3, and #4.
Text by me above is hereby placed in the public domain
More information about the Squeak-e