[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Modules vs. dynamic binding
Date: Tue, 12 Dec 89 06:38:57 est
From: firstname.lastname@example.org (Chris Hanson)
Scott, this technique you propose is a useful one, but I don't believe
it provides a replacement for dynamic binding. The problem with the
technique is that the procedure `read' cannot be embedded in another
program unless the embedding program is also parameterized in a
similar way (by "embedded" I mean that the variable `read' is bound in
some closing environment of the embedding program).
To properly take advantage of this technique (as you point out), every
embedding program must be parameterized, and furthermore the
parameters of the embedded program must also be parameters of the
I don't think the latter is true at all. Many programs will use READ,
for instance, but will not want to inherit the various parameters of the
reader from programs in which they are embedded. In fact, the original
motivating example I gave was of just such a case.
Clearly nobody wants
to write all of that specialization by hand, and yes, all this "late
binding" can be hidden by a module system; but what about the program
that occasionally specializes itself as it runs? Does the module
system know how to create new programs on the fly, or is it restricted
to describing more static relationships?
Remember that "creating a new program" amounts to evaluating (i.e.,
closing) a set of lambda-expressions. It's a familiar, primitive, and
efficient operation (at least, it had better be).
Ultimately this "module system" becomes an integral part of the
language -- it has introduced a new kind of binding with "dynamic"
No, that's exactly what it hasn't done. It is using the same old kind
of binding that we all know and love to accomplish the same ultimate
purpose as dynamically bound parameters, but in a different way.
What are the semantics of this binding? Is it
different from what we now think of as "dynamic binding"? Is this
really a new idea or just a new implementation of an old idea?
I will vigorously defend myself against any intimation that I am saying
anything new. :-) But no, it is neither of those things. It is, at
best, a new application of an existing implementation of an old idea.
Another solution to this problem was invented by John Lamping a few
years ago: he introduced another kind of variable that could be bound
after the program was constructed. These variables can be considered
to be "holes" in the program, which can be filled in at any time by a
virtual-copy process that produced a new program in which a particular
set of "holes" was filled. Program fragments can be combined into
larger program fragments, independent of whether they have "holes";
"matching holes" in two program fragments become identified in the
combined fragment. With this solution, `read' would have such a
variable for its radix, and this variable would be unspecified when
`read' was defined. You could then embed `read' in some big program,
and just before you were ready to run it, you could specialize the
embedding program with the desired radix.
This sounds complicated and inelegant by comparison with what I propose.
Lamping's solution has some major advantages over what you propose:
* The embedding program doesn't have to know anything about what
"holes" `read' has.
I consider that a disadvantage -- a serious one. Indeed, it is
precisely one of those properties of the dynamic-binding approach that I
am complaining about.
* The values being supplied to the "holes" can be collected
together in an environment and supplied all at once. A "default
environment" can easily be created, and the user can override
particular bindings in that environment by shadowing.
This is a good idea, and I would certainly want to incorporate it.
* It is clearly a change to the language itself rather than a
system that at least nominally is not a fundamental part of the
Again, I consider this a disadvantage.
But are either of these solutions really so different from dynamic
binding? You claim that dynamic binding is destructive to modularity,
but with the implementation proposed by Pavel the designer must
clearly state the intention that a particular parameter may be
dynamically bound, so the parameter is clearly part of the program's
abstraction boundary (if you can get your hands on it).
I don't see that. I don't see what's to stop me from defining a bunch
of variables at top-level to be bound to Dynamics (or whatever they wind
up being called) and then just using them like special variables.
Granted, such parameters are logically part of the program's
abstraction; my observation is that in practice, they don't wind up
being specified as such. That's part of my complaint.
I think this topic is an interesting one that falls between the
cracks: it's a little too dynamic for modules, and not dynamic enough
for procedural arguments. I'd like to see some work done on
understanding this; I suspect that Lamping's work is a good first step
(implementing his language efficiently is quite challenging).
(Implementing my proposal efficiently is quite straightforward.)
On the other hand, I have a strong feeling that dynamic binding is the
best solution to this problem for Scheme -- a better solution may
require changes that are fundamental enough that the result may no
longer be "Scheme-like".
That may well be true; although the funny thing is, the longer I think
and talk about this, the more convinced I am that my proposal is
entirely appropriate for Scheme. I don't always convince myself so