Robert Dodier <robert.dodier at gmail.com> wrote:
On 1/11/12, Steve Haflich <smh at franz.com> wrote:
> Proclamations (aka declamations) such as are estabished by the
> macroexpansions if DEFVAR etc. affect all subsequently-compiled or
> executed bindings and references.
That's unfortunate, isn't it? since it means, in effect, that there is
in fact no lexical scope in Common Lisp, because the behavior of
a given snippet of code can only be understood by considering the
entire program.
I understand your argument, but it is either incorrect in a strict
language-lawyer sense, or irrelevant in that the issue almost never
causes problems in real code. Since I'm a language lawyer (:-) I'll
make that response first.
It is true that when one writes code that lambda binds a variable such
as cl-user::foo one cannot be absolutely certain that some remote, even
irrelevant, module has sneakily declaimed foo to be globally special.
(The package system is designed to reduce the possibility of inadvertent
name collisions, but the package system remains in Chapter 11
(U.S. bankruptcy law) as X3J13 nonbindingly instructed the ANS editor.)
If some body of code were either so pernicious or so disorganized, one
would be wise not to use it.
Nonetheless, writing as language lawyer, it is indeed possible to
guarantee that a variable is bound lexically:
(defun foo (x)
(let ((#1=#:y (1+ x)))
(bar #1#)))
It is guaranteed that the gensym #:y will bound lexically, since that
variable name is visible nowhere else than this defun form when it is
read by the reader.
(Of course, no one _ever_ does this, even though macrology could do it
automatically. But I digress.)
A related issue (actually the same issue) would be a promiscuous
declamation like
(declaim (type (mod 256) foo))
which (when not obeyed) could cause the compiler to miscompile
references to the special variable "foo". (It would, fortunately, not
affect any lexical binding.) There is nothing special [sic] about a
special declaration.
The above comments, other than being a virtuoso exercise of language
lawyering, are otherwise both uninteresting and irrelevant. My serious
comment follows:
Common Lisp binding and scoping semantics are about 20 years old. They
are in practice, and in most details, somewhat older, but they are based
on years of post-MACLISP practice, are consistent, and when reasonable
conventions are used generally don't cause practical programming
problems. Maxima binding semantics date from MACLISP, about 50 years
ago, before the distinction between "special" and "lexical" bindings had
been clearly delineated in practice. The issue you suggest about a
pernicious promiscuous special proclamation is a real issue, but it is
almost never an actual issue, assuming accepted reasonable coding
practices. That is why CL programmers always name special variables
with leading and trailing *stars*. (Sometimes low-level constants are
decorated differently, e.g. .data-offset. or %data-offset%.) These
conventions both reduce the possibility of collisions and improve
readability of code.
I've previously proposed, perhaps mischievously, that the code in both
Maxima implementation and Maxima user applications would be improved if
the language were changed to mimic CL bding and scoping semantics. This
is an honest and sincerely-considered opinion; it is mischievous only
because that would be an impractically-high back compatibility hill to
traverse.
(I'd apologize here if this message is unbearably tedious, but certainly
no reader will have gotten far enough to read the apology.)