Questions - RE: Dynamic scoping

Avi Bryant avi at beta4.com
Tue Jan 28 23:34:51 UTC 2003



On Tue, 28 Jan 2003, Swan, Dean wrote:

> Please pardon my interruption, but 90% of this thread just makes my
> head spin, so I have some questions:
>
> 	1) Is it correct that this whole dynamic scoping thing is
> 		limited to resolving references to named objects within
> 		the context of an executing method?

Yes.  "Dynamic scoping" and "lexical scoping" are the two common ways for
variables to be resolved.  Smalltalk is lexically scoped, which means that
variables names are resolved according to where the current method (or
block) was created; early versions of lisp, for example, were dynamically
scoped, which means that variable names are resolved according to where
the current method was called from.

For example, say you have a method like this:

UndefinedObject>>blockAnswering: x
  ^ [x]

And now in a workspace I do this:

|block x|
block := nil blockAnswering: 42.
x := 23.
block value.

In Smalltalk, the block will return 42, because "x" is resolved by looking
at the scope in which the block was created, and the first binding for the
name "x" it finds is the parameter to #blockAnswering:, which is 42.

In a dynamically scoped language, the same code would return 23, because
it would look up the call stack instead, and the first "x" it would find
is the one in the workspace.

For hopefully obvious reasons, lexical scoping is almost always what you
want.  In a few cases, however, dynamic scoping is quite useful.  All
languages I know of use dynamic scoping for exception handling, for
example: the current handler is found by walking up the call stack, not
the lexical scope.

Usually, you can think of dynamic scope as a fancy way of talking about
"thread local variables", and it's useful in the same kinds of places.
In Smalltalk, however, there's not always a one-one mapping between
thread/Process and call stack - by sending #swapSender: to thisContext,
for example, I can switch to a new call stack without changing Process.
Because the Seaside web framework makes use of this kind of trick, I need
to be more concerned than most people about the exact distinctions between
"true" dynamic scope (which uses the call stack) and simple thread local
storage.  In particular, since Seaside allows the user (through the web
browser's back button) to *return multiple times* to the same call stack,
I have to be sure that dynamic state (like the current exception handlers,
for example) is properly restored every time they do that.

However, most of you can ignore Stephen and my babblings if you want to
;).

> 	2) If the answer to 1) is "yes", then couldn't the dynamic
> 		scoping be accomplished by using accessor
> 		methods instead of direct references to named objects?

> 		If I'm understanding what is desired here, I'm not sure
> 		why we need another mechanism for runtime binding of
> 		names.  It seems like you could accomplish the dynamic
> 		scoping with just accessors and thisContext to trace
> 		sender chains.

I think Anthony's code does largely that.  It doesn't do what I want,
however, because there's no guarantee that the values will be restored if
I reenter the same dynamic scope.

> 	3) Is the idea here related to namespaces, except with a
> 		runtime context dependency?

That was how this thread originally got started, with somebody (I think
Lex) proposing that classes could be resolved using dynamic scope instead
of being globals.  That's not why I happen to be interested in dynamic
scope, which probably just made what I was saying more confusing (though I
think Stephen understood that).  Apologies to those caught in the
crossfire.

;)
Avi



More information about the Squeak-dev mailing list