Shallow binding of POP-2 variables arose because the 4130 only had one
index register which we needed to use as a stack pointer, since that
provided a general low-space-overhead way of calling functions in what was
a modified functional language. This always appeared as the wrong way of
doing things, since the lambda calculus calls for lexical binding, but was
justified on the grounds that existing lexical binding techniques (as
embodied in Algol) were also wrong, since they didn't provide the
possibility of returning a function as a result of a function. We were of
course aware of the debugging advantages of having part of the environment
available for very little cost.
However the price of dynamic binding became very obvious when we
implemented continuations (done by Ray Dunn in a weekend...) since the
"state", even of a functional program, was distributed throughout the
machine. Moreover we had to complicate the continuation concept by
introducing a "stack barrier" to give us something like efficiency.
To this day we can't compete with Scheme and JNML in generating
light weight continuations.
My own practice these days is to avoid any dlocals in code I actually
write, by using an extra argument to any function (usually called "Env")
which is a data-structure that bundles up any kind of style switch.
Robin.
|