I have included, below, Jeff's excellent listing of ANSI statements regarding variables which are neither declared special nor have a clear lexical binding. I wish to: 1. Sumarize my understanding of the position. 2. Add one other reference, for the record, and ask a question about one of Jeff's references. 3. Raise two issues which all this still leaves me confused about.
1. Summary:
It is an error for a variable which does not have a lexical binding to not be explicitly declared special in some way (such as a declamation or local declaration). "It is an error" has the usual meaning that the behavior is not defined. In this particular case, this means that implementations may or may not signal warnings or errors at either compile or run time. No conforming program can rely on undeclared variables being special.
It is acknowledged that this makes it difficult to use free variables in the interpreter. Because of this, all current implementations happen to treat undeclared free variables as special, at least in the interpreter. At least one major implementation, CMUCL, make a global special declamation for all free variables, whether compiled or interpreted. This does not conflict with the above, but has the perhaps unfortunate effect of changing the semantics of otherwise conforming code once some user has mistakenly referenced an undeclared free variable (in interpreted or compiled code).
2. References:
Section 3.2.2.3 Semantic Constraints, says:
All conforming programs must obey the following constraints, which are designed to minimize the observable differences between compiled and interpreted programs: ... Special proclamations for dynamic variables must be made in the compilation environment. Any binding for which there is no special declaration or proclamation in the compilation environment is treated by the compiler as a lexical binding.
At first glance, one might think this contradicts the above, but I interpret this is specifying that the compiler must assume the variable is lexical and look for a lexical binding. It is then, presumably, "an error", when a compiler tries to look up a lexical binding and doesn't find one.
Question: Jeff quoted an X3J13 issue called "PROCLAIM LEXICAL", noting that the wording of the issue was changed over time. I cannot find an issue with this name in Kent's excellent HyperSpec. Is it there? Can someone give me a pointer to it?
3. Outstanding issues:
I. Once a variable has been declaimed special, how does one make it unspecial? (Do I need to clarify why I think this is important?)
II. Consider the following: (let ((x 1)) (compile 'foo '(lambda () x)))
I feel that on the one hand, the reference to x in the lambda is not a variable refering to the binding of the lexical variable, but simply the symbol x in a quoted list that happens to begin with the word lambda. The list is not a "lambda expression". On the other hand, the definition of COMPILE specifically says that it IS a lambda expression. Also, this list must be compiled in the compilation environment. The end of section 3.2.1 Compiler Terminology says that COMPILE is a run-time compiler for which the run-time environment and compiler startup environment are the same, and that the compilation environment inherits (ultimately) from the compiler startup environment. Since the run-time environment in which compile was called clearly had a lexical binding for X, this is also true in the compilation environment.
The dictionary defintion for COMPILE says that the lambda expression is coerced to a function, and coercing a lambda-expression to a function in the body of the LET would also ordinarily enclose the binding of X.
It then goes on to say, though, that: The consequences are undefined if the lexical environment surrounding the function to be compiled contains any bindings other than those for macros, symbol macros, or declarations.
Since this is the most specific statement, it takes precedence. However, I would feel more comfortable if there was some acknowledgement that the second argument to COMPILE was not a full fledged lambda expression and that its coercion to a funciton did not follow the usual semantics regarding the capture of lexical bindings.
I note that since the consequence of this case are undefined, it does leave open the possibility that an implemenation might make use of the lexical binding. Of course, no conforming program could rely on this extension, and it raises another issue. If the compiler can reference lexical bindings in a run-time environment outside the scope of the compiler, then the reference I cite above (section 2) would want to be handled by such implementations by doing a run-time lexical variable lookup, as though in an interpreter. This, in turn, raises the issue of run-time maniplulation of environments by user code. While it seems that "madness this way lies", I could imagine wanting to use a debugger in which the lexical (and dynamic?) environment from the current stack frame were available to me in evaluating forms within the debugger. (I remember being shocked as freshman that this was NOT what happened.) One might make use of some of these features to write such a debugger.
So, the question is: Is this analysis correct? Is the behavior of undeclared non-lexical variables undefined, and does this include X in the COMPILE example? Is an implementation free to define the behavior consistent with the concept of looking (at run or compile time) for a lexical variable and using it, and failing that, to silently use the global value?
> In article <3049754333170...@arcana.naggum.no> Erik Naggum <e...@naggum.no> writes: > >Robert Munyer's exceedingly lengthy diatribe seems to hinge on one issue: > >whether the semantics of `setq' at top-level of a variable that has not > >been declared special is defined by Common Lisp. I can't see that it is. > >I'd like Robert to show me how he found the semantics of this to be defined > >by the language specification since he makes so many conclusion based on > >his assumption that its semantics _is_ defined.
> It's not clear that the standard is entirely consistent with itself. > In section 3.1.2.1.1.2, Dynamic Variables, it says
> A dynamic variable can be referenced at any time in any program; > there is no textual limitation on references to dynamic variables. At > any given time, all dynamic variables with a given name refer to > exactly one binding, either in the dynamic environment or in the > global environment.
> ...
> A dynamic variable can be referenced outside the dynamic extent of a > form that binds it. Such a variable is sometimes called a ``global > variable'' but is still in all respects just a dynamic variable whose > binding happens to exist in the global environment rather than in some > dynamic environment.
> Yet in the glossary we find:
> dynamic variable n. a variable the binding for which is in the > dynamic environment. See special.
> Nothing about the global environment _there_.
> 3.1.2.1.1.2 also says
> A variable is a dynamic variable if one of the following conditions hold:
> * It is locally declared or globally proclaimed special.
> * It occurs textually within a form that creates a dynamic binding > for a variable of the same name, and the binding is not shadowed[2] > by a form that creates a lexical binding of the same variable name.
> The 1st item just above suggests that Eric may be right, so far as the > ANSI standard is concerned. However, "if" is not the same as "only if" > or "if and only if", so perhaps things aren't as clear here as they > might be. "No textual limitation" and the (so far as I know) lack > of anything that says the semantics are _not_ defined, suggests that > free refs are refs to global special variables. (N.B. special but > not _proclaimed_ special, an important distinction. Special > proclamations make all bindings of the name special, declarations don't.)
> In 3.1.2.1.1, Symbols as Forms, we find:
> If a form is a symbol that is not a symbol macro, then it is the > name of a variable, and the value of that variable is returned. There > are three kinds of variables: lexical variables, dynamic variables, > and constant variables. A variable can store one object. The main > operations on a variable are to read[1] and to write[1] its value.
> There's no hint here (or anywhere else that I've found) that's > another case: variables that aren't lexical or constant yet not > dynamic either because there's hasn't been a special proclamation > or declaration. Moreover, the description of setq uses examples such > as the following without any declarations or proclamations:
> ;; A simple use of SETQ to establish values for variables. > (setq a 1 b 2 c 3) => 3 > a => 1 > b => 2 > c => 3
> ... if the symbol occurs textually within a program construct > that creates a _binding_ for a variable of the same name, then > the reference is to the variable specified by the binding; if > no such program construct textually contains the reference, > then it is taken to refer to the special variable of that name.
> The description of setq (p 121) is less clear than it might be, > since it says only that "the usual rules" determine whether > the variable being assigned to is lecical or dynamic. But I > think it's fair to conclude at least that there's not meant > to be a difference between the rules for assignment and the > rules for reference.
> Section 7.1.1, Reference (p 114) says that whether the variable > is special or lexical depends on the presence of absence of a > special declaration; but I don't think that is meant to
Erik Naggum <e...@naggum.no> wrote: > Robert Munyer's incessant bickering has made me realize it was > a mistake to try to discuss this with him.
Again you have weaseled out of answering my questions, and chosen to insult me instead. Trying to have a fair debate with you is like trying to catch a slippery fish with one's bare hands. Every time I try to get you to commit to ANYTHING, you evade my questions and respond with insults or sarcasm.
> I apologize for the spectacle.
As well you should. You have a lot to learn about how to participate in a discussion without antagonizing people. During the height of this "spectacle," I received an e-mail from another reader of the newsgroup (whom I shall not name). He referred to you as a "pig" who has a "history of arrogance, stubbornness, and irascibility." I suspect he is just one of a long line of people whom you have abused in various newsgroups, for no reason at all.
My own experience is a case in point. I didn't make any disparaging statements about you until after you wrote three articles against me. You "corrected" me once, and then attacked me several times, in articles which grew increasingly condescending and sarcastic -- all because I made use of an aspect of Common Lisp that you didn't understand, in an article that wasn't even directed at you.
Barry Margolin has also accused me of being wrong in this thread, but he managed to do it without being rude, condescending, snide, sarcastic, and evasive. So I can still have a polite debate with him, and not have to waste my time in flame wars. You should look through his articles, and take a lesson. Maybe then you will not end up convincing any more people that you are a "pig."
I hope your first sentence above means that you are going to get out of this thread, and let the rest of us discuss technical issues in peace.
> A variable is a dynamic variable if one of the following > conditions hold:
> * It is locally declared or globally proclaimed special.
> * It occurs textually within a form that creates a dynamic > binding for a variable of the same name, and the binding > is not shadowed[2] by a form that creates a lexical binding > of the same variable name.
> The 1st item just above suggests that Eric may be right, so far > as the ANSI standard is concerned. However, "if" is not the same > as "only if" or "if and only if", so perhaps things aren't as > clear here as they might be. "No textual limitation" and the > (so far as I know) lack of anything that says the semantics are > _not_ defined, suggests that free refs are refs to global special > variables. (N.B. special but not _proclaimed_ special, an > important distinction. Special proclamations make all bindings > of the name special, declarations don't.)
Based on those last two sentences I think you actually agree with me, not with Erik. Erik's latest attempt at spin control seems to be a claim that an implementation is allowed (under both CLtL2 and the ANSI standard) to PROCLAIM a symbol special, if you use SETQ to give it a global value. I'm not sure if Erik thinks this also applies to SET and SETF and (SETF SYMBOL-VALUE), because he refuses to answer my questions.
> In 3.1.2.1.1, Symbols as Forms, we find:
> If a form is a symbol that is not a symbol macro, then it is > the name of a variable, and the value of that variable is > returned. There are three kinds of variables: lexical variables, > dynamic variables, and constant variables. A variable can store > one object. The main operations on a variable are to read[1] > and to write[1] its value.
> There's no hint here (or anywhere else that I've found) that's > another case: variables that aren't lexical or constant yet not > dynamic either because there's hasn't been a special proclamation > or declaration.
Remember that in the HyperSpec, the unadorned term "variable" refers to a binding, not to the symbol that names the binding. I am not saying that a BINDING can be something other than lexical or constant or dynamic; I am saying that a NAME can have a lexical binding and a dynamic binding at the same time -- and in fact, that dynamic binding can be global. If you assign a global value to a variable name without proclaiming that name to be special, then you can still have lexical bindings on that same variable name.
> Moreover, the description of setq uses examples such as the > following without any declarations or proclamations:
> ;; A simple use of SETQ to establish values for variables. > (setq a 1 b 2 c 3) => 3 > a => 1 > b => 2 > c => 3
The three bindings created here are global and therefore dynamic. But the three symbols have not been proclaimed special, so they are still available for either lexical or dynamic binding (or both) in the future of this Lisp session.
> ... if the symbol occurs textually within a program construct > that creates a _binding_ for a variable of the same name, then > the reference is to the variable specified by the binding; if > no such program construct textually contains the reference, > then it is taken to refer to the special variable of that name.
Yes, I think this is better and clearer than the corresponding section of the HyperSpec.
> The description of setq (p 121) is less clear than it might be, > since it says only that "the usual rules" determine whether the > variable being assigned to is lecical or dynamic. But I think > it's fair to conclude at least that there's not meant to be a > difference between the rules for assignment and the rules for > reference.
I agree. To have assignment work differently would seem "strange."
> However, the situation is muddued by the pactice in many > implementations of giving warnings on references to undeclared > free variables. Language such as "assumed to be special" is > often used. This is because implementors suspect that most such > cases are unintentional and indicate mistakes in the code.
Actually, I don't find this warning to be muddy -- as long as you understand that the phrase "assumed to be special" refers to that one particular reference, not to EVERY binding or reference that happens to have the same name. This warning just means that
(defun foo () x)
is replaced with
(defun foo () (declare (special x)) x)
rather than with
(declaim (special x)) (defun foo () x)
> > barring any overlooked clauses which Robert will bring to my > > attention, whatever it is that he's trying to distinguish > > between `setq' and `defvar' at top-level is purely a matter of > > how _implementations_ differ in implementing undefined semantics.
> I don't think so. For one thing, there isn't much variation > between implementations. So far as I know (and I've used over > a dozen Common Lisps), they all interpret references (including > in assignments) to undeclared free variables as refrences to the > special variable.
Right. This behavior is specified by CLtL2 section 5.1.2:
The general rule is that if the symbol occurs textually within a program construct that creates a binding for a variable of the same name, then the reference is to the variable specified by the binding; if no such program construct textually contains the reference, then it is taken to refer to the special variable of that name.
> They differ in whether and when they give a warning. Most > implementations do not give a warning except when compiling. > CMU CL is an exception. I suspect it's the only one. In any > case, it has the behaviour I'd expect from p 70. E.g.
> * (setq x 1) > Warning: Declaring x special. > 1
> * (setq x 2) > 2
> * (defun fx () x)
> * (fx) > 2
An important question here is whether the symbol X was PROCLAIMED to be special. A proclamation is a type of declaration, so the warning message above doesn't really tell us whether SETQ proclaimed the symbol X to be special, or merely declared that one particular use of X to be special. And the function FX doesn't help us, because it would always return 2, regardless of whether the symbol X has been proclaimed to be special.
Apparently you have a CMU CL handy. If so, could you please use it to evaluate the following:
and let us know what it says? The results should be:
These proclaim special: DEFPARAMETER DEFVAR These do not: SET SETF (SETF SYMBOL-VALUE) SETQ
In fact, since you've used over a dozen Common Lisps, you probably have several of them handy. It would be great if you could evaluate the above code in each of them. Other people reading this, please feel free to contribute results from whichever implementation of Common Lisp you are using.
> > the question is: does ANSI Common Lisp (or CLtL2 for that > > matter) define the semantics of `setq' at top-level, including > > whether the symbol should be declared or proclaimed special?
> Well, neither the standard not CLtL 2 makes things entirely and > explicitly clear.
My own understanding is that no side effect is allowed unless it is documented. Therefore lack of specific mention means that the side effect is not allowed.
Otherwise, all hell would break loose. You could have any kind of construct producing any kind of side effect, because the standard very rarely states explicitly that a certain construct will not have a certain side effect. It is just taken for granted that only documented side effects can exist.
Also, any implementation which follows Erik's suggestion, and proclaims symbols special when not explicitly required to by the standard, will be unable to evaluate standard example code successfully. For example, see the code in the section on EVAL:
You can't argue that an implementation is correct, if it can't even evaluate the code examples in the standard!
> But I've never, before this, heard it suggested that the semantics > was not defined, not even in X3J13 discussions that covered this > area when considering the PROCLAIM-LEXICAL issue. It was noted > that the warnings mentioned above made it a pain in practice to > use undeclared free refs; but that's about as far as it went.
> For instance, from PROCLAIM-LEXICAL version 2:
This PROCLAIM-LEXICAL document to which you refer is very interesting. This is the first time I've heard that anyone on the committee has addressed
...
In article <32231138.31DFF...@elwoodcorp.com> "Howard R. Stearns" <how...@elwoodcorp.com> writes:
>I have included, below, Jeff's excellent listing of ANSI statements >regarding variables which are neither declared special nor have a clear >lexical binding. I wish to: > 1. Sumarize my understanding of the position. > 2. Add one other reference, for the record, and ask a question about >one of Jeff's references. > 3. Raise two issues which all this still leaves me confused about.
>1. Summary:
> It is an error for a variable which does not have a lexical binding to > not be explicitly declared special in some way (such as a declamation > or local declaration).
No way. I've seen nothing that says or implies that it is an error, and it's odd that you regard this paragraph of yours as a summary. It certainly doesn't reflect the discussion *I've* seen.
> "It is an error" has the usual meaning that > the behavior is not defined.
But people have been using that the other way around, as if "not explicitly defined anywhere" meant "is an error".
> In this particular case, this means > that implementations may or may not signal warnings or errors at > either compile or run time.
I have seen no justification for signalling an error. I'm not sure in what cases warnings are permitted, but in practice they certainly include cases that are allowed in conforming code and that are not "an error".
> No conforming program can rely on > undeclared variables being special.
It's arguable that x has been declared special in line 2, but it certainly hasn't been in line 1, and I've never seen even a warning (not even in CMUCL) for such things as line 1. Yet it's clear from the HyperSpec and CLtL that symbol-value reads and writes the value of the dynamic (ie, special) variable. So x must have been special before any declaration or proclamation had occurred. (And line 2 is relying on this.)
>It is acknowledged that this makes it difficult to use free variables in >the interpreter.
It is? By?
> Because of this, all current implementations happen to >treat undeclared free variables as special, at least in the interpreter.
Can you tell me one that doesn't do this in the compiler? At most, there's a warning when the code is compiled (so far as I've seen).
>At least one major implementation, CMUCL, make a global special >declamation for all free variables, whether compiled or interpreted.
> All conforming programs must obey the following constraints, which are >designed to minimize the observable differences between compiled and > interpreted programs: > ... > Special proclamations for dynamic variables must be made in the > compilation environment. Any binding for which there is no special > declaration or proclamation in the compilation environment is treated > by the compiler as a lexical binding.
>At first glance, one might think this contradicts the above, but I >interpret this is specifying that the compiler must assume the variable >is lexical and look for a lexical binding. It is then, presumably, "an >error", when a compiler tries to look up a lexical binding and doesn't >find one.
Note that it says "any _binding_" (emphasis added) and not "any reference". So if the compiler sees
(let ((x 1)) ...)
and there's no special declaration/proclamation in the compilation env, the x is bound as a lexical variable.
>Question: Jeff quoted an X3J13 issue called "PROCLAIM LEXICAL", noting >that the wording of the issue was changed over time. I cannot find an >issue with this name in Kent's excellent HyperSpec. Is it there? Can >someone give me a pointer to it?
It wasn't passed, hence isn't in the HyperSpec. But that doesn't invalidate its description of the problem and the proposals.
>3. Outstanding issues:
> I. Once a variable has been declaimed special, how does one make it >unspecial? (Do I need to clarify why I think this is important?)
There's no standard way to do so.
> II. Consider the following: > (let ((x 1)) (compile 'foo '(lambda () x)))
Let's please not get into a discussion of COMPILE. It will complicate everything for little gain.
> A variable is a dynamic variable if one of the following > conditions hold:
> * It is locally declared or globally proclaimed special.
> * It occurs textually within a form that creates a dynamic > binding for a variable of the same name, and the binding > is not shadowed[2] by a form that creates a lexical binding > of the same variable name.
> The 1st item just above suggests that Eric may be right, so far > as the ANSI standard is concerned. However, "if" is not the same > as "only if" or "if and only if", so perhaps things aren't as > clear here as they might be. "No textual limitation" and the > (so far as I know) lack of anything that says the semantics are > _not_ defined, suggests that free refs are refs to global special > variables. (N.B. special but not _proclaimed_ special, an > important distinction. Special proclamations make all bindings > of the name special, declarations don't.)
Based on those last two sentences I think you actually agree with me, not with Erik. Erik's latest attempt at spin control seems to be a claim that an implementation is allowed (under both CLtL2 and the ANSI standard) to PROCLAIM a symbol special, if you use SETQ to give it a global value. I'm not sure if Erik thinks this also applies to SET and SETF and (SETF SYMBOL-VALUE), because he refuses to answer my questions.
> In 3.1.2.1.1, Symbols as Forms, we find:
> If a form is a symbol that is not a symbol macro, then it is > the name of a variable, and the value of that variable is > returned. There are three kinds of variables: lexical variables, > dynamic variables, and constant variables. A variable can store > one object. The main operations on a variable are to read[1] > and to write[1] its value.
> There's no hint here (or anywhere else that I've found) that's > another case: variables that aren't lexical or constant yet not > dynamic either because there's hasn't been a special proclamation > or declaration.
Remember that in the HyperSpec, the unadorned term "variable" refers to a binding, not to the symbol that names the binding. I am not saying that a BINDING can be something other than lexical or constant or dynamic; I am saying that a NAME can have a lexical binding and a dynamic binding at the same time -- and in fact, that dynamic binding can be global. If you assign a global value to a variable name without proclaiming that name to be special, then you can still have lexical bindings on that same variable name.
> Moreover, the description of setq uses examples such as the > following without any declarations or proclamations:
> ;; A simple use of SETQ to establish values for variables. > (setq a 1 b 2 c 3) => 3 > a => 1 > b => 2 > c => 3
The three bindings created here are global and therefore dynamic. But the three symbols have not been proclaimed special, so they are still available for either lexical or dynamic binding (or both) in the future of this Lisp session.
> ... if the symbol occurs textually within a program construct > that creates a _binding_ for a variable of the same name, then > the reference is to the variable specified by the binding; if > no such program construct textually contains the reference, > then it is taken to refer to the special variable of that name.
Yes, I think this is better and clearer than the corresponding section of the HyperSpec.
> The description of setq (p 121) is less clear than it might be, > since it says only that "the usual rules" determine whether the > variable being assigned to is lecical or dynamic. But I think > it's fair to conclude at least that there's not meant to be a > difference between the rules for assignment and the rules for > reference.
I agree. To have assignment work differently would seem "strange."
> However, the situation is muddued by the pactice in many > implementations of giving warnings on references to undeclared > free variables. Language such as "assumed to be special" is > often used. This is because implementors suspect that most such > cases are unintentional and indicate mistakes in the code.
Actually, I don't find this warning to be muddy -- as long as you understand that the phrase "assumed to be special" refers to that one particular reference, not to EVERY binding or reference that happens to have the same name. This warning just means that
(defun foo () x)
is replaced with
(defun foo () (declare (special x)) x)
rather than with
(declaim (special x)) (defun foo () x)
> > barring any overlooked clauses which Robert will bring to my > > attention, whatever it is that he's trying to distinguish > > between `setq' and `defvar' at top-level is purely a matter of > > how _implementations_ differ in implementing undefined semantics.
> I don't think so. For one thing, there isn't much variation > between implementations. So far as I know (and I've used over > a dozen Common Lisps), they all interpret references (including > in assignments) to undeclared free variables as refrences to the > special variable.
Right. This behavior is specified by CLtL2 section 5.1.2:
The general rule is that if the symbol occurs textually within a program construct that creates a binding for a variable of the same name, then the reference is to the variable specified by the binding; if no such program construct textually contains the reference, then it is taken to refer to the special variable of that name.
> They differ in whether and when they give a warning. Most > implementations do not give a warning except when compiling. > CMU CL is an exception. I suspect it's the only one. In any > case, it has the behaviour I'd expect from p 70. E.g.
> * (setq x 1) > Warning: Declaring x special. > 1
> * (setq x 2) > 2
> * (defun fx () x)
> * (fx) > 2
An important question here is whether the symbol X was PROCLAIMED to be special. A proclamation is a type of declaration, so the warning message above doesn't really tell us whether SETQ proclaimed the symbol X to be special, or merely declared that one particular use of X to be special. And the function FX doesn't help us, because it would always return 2, regardless of whether the symbol X has been proclaimed to be special.
Apparently you have a CMU CL handy. If so, could you please use it to evaluate the following:
and let us know what it says? The results should be:
These proclaim special: DEFPARAMETER DEFVAR These do not: SET SETF (SETF SYMBOL-VALUE) SETQ
In fact, since you've used over a dozen Common Lisps, you probably have several of them handy. It would be great if you could evaluate the above code in each of them. Other people reading this, please feel free to contribute results from whichever implementation of Common Lisp you are using.
> > the question is: does ANSI Common Lisp (or CLtL2 for that > > matter) define the semantics of `setq' at top-level, including > > whether the symbol should be declared or proclaimed special?
> Well, neither the standard not CLtL 2 makes things entirely and > explicitly clear.
My own understanding is that no side effect is allowed unless it is documented. Therefore lack of specific mention means that the side effect is not allowed.
Otherwise, all hell would break loose. You could have any kind of construct producing any kind of side effect, because the standard very rarely states explicitly that a certain construct will not have a certain side effect. It is just taken for granted that only documented side effects can exist.
Also, any implementation which follows Erik's suggestion, and proclaims symbols special when not explicitly required to by the standard, will be unable to evaluate standard example code successfully. For example, see the code in the section on EVAL:
You can't argue that an implementation is correct, if it can't even evaluate the code examples in the standard!
> But I've never, before this, heard it suggested that the semantics > was not defined, not even in X3J13 discussions that covered this > area when considering the PROCLAIM-LEXICAL issue. It was noted > that the warnings mentioned above made it a pain in practice to > use undeclared free refs; but that's about as far as it went.
> For instance, from PROCLAIM-LEXICAL version 2:
This PROCLAIM-LEXICAL document to which you refer is very interesting. This is the first time I've heard that anyone on the committee has addressed this
...
Robert Munyer, if I ever doubted that you were unreasonable, your last note has certainly removed any shred of it. it is abundantly clear that your purpose now is revenge, rather than any purported "technical" issues.
if you should return to technical discussions, please, try to respect that those with whom you try to discuss anything technical might want to refer you to authoritative documents and standards instead of including them in their replies or paraphrasing them with an added chance of introducing more confusion. you strongly suggest that you have higher regard and respect for USENET contributions than for standards documents, and this is an attitude so mind-bogglingly irrational that if I come across as saying "you are stupid, Robert Munyer", it is because that is exactly what I think.
BTW, anonymous references to private communication, ostensibly to avoid being the one to slander somebody else, is the best evidence yet to be found on USENET of how low a person can get. such behavior reveals an amazingly cavalier attitude to reproducibility of observations and credibility of conclusions, and points to a fundamental misunderstanding of how legitimate observations and conclusions are made. it is no wonder at all that such a person is incapable of reading a standards document to learn of the facts of a specification, when he obviously believes that it furthers his cause to make such pathetic attacks solely on his opponent. and to have the gall to make the unfounded claim that he wants to discuss technical issues at the same time is...
you are in fact wrong on your technical points, Robert Munyer. there is nothing more than "read the fine manual" to tell you. since you refuse to do that, and instead continue to pose irrelevant questions about what people think or believe, based on your own misunderstood assumptions, what exactly did you expect to receive? what would you do with the answers you got? would you use them in anonymous references in discussions with your colleagues that you are somehow correct in your assumptions? would you at any one point go and consult the specification to learn how things _should_ have been done, instead doing a Gallup poll on what a representative sample of the population might think? standards are written by the best people we can find. anybody at all can have opinions. this is why we have standards written by experts instead of Gallup polls on USENET every time we wish to know what Common Lisp, the language, specifies.
and it is true, I find unbridled display of arrogant ignorance to be the worst aspect of USENET. and it is true, I do treat people who refuse to listen to authoritative sources and instead go on to ask _people_ what they think, as fundamentally misguided and extremely unlikely to produce anything of reasonable value in a discussion, because they discuss not what is, but what people believe.
finally, Robert Munyer, you do most emphatically not _have_ to waste your time in flame wars. if you _want_ to waste your time in flame wars, that is your very own choice. sometimes, it is more effective to shut up than to continue to make the crux of your argument that somebody else is a "pig".
you said you had a technical argument. I'll believe it when I see it. I don't think it is possible to have technical discussion with people whose mission it is to convince the world of their own personal misconceptions, including, but not limited to meaningless and pathetic slandering of others. I think a technical discussion must refer to something that is impersonal, such as a standard specification for a programming language.
In article <32231138.31DFF...@elwoodcorp.com>, Howard R. Stearns <how...@elwoodcorp.com> wrote:
> 1. Summary:
> It is an error for a variable which does not have a lexical > binding to not be explicitly declared special in some way (such > as a declamation or local declaration). "It is an error" has > the usual meaning that the behavior is not defined. In this > particular case, this means that implementations may or may > not signal warnings or errors at either compile or run time. > No conforming program can rely on undeclared variables being > special.
Sorry, none of the above is true. There is plenty of code in the standard that does exactly what you are saying cannot be done. I understand how you came to this conclusion (see below) but it is not correct.
> At least one major implementation, CMUCL, make a global special > declamation for all free variables, whether compiled or interpreted.
If this is true, it is a bug in CMUCL.
If anyone reading this has a CMU CL handy, It would be helpful if you could use it to evaluate the test code in my 8/28 article (message id <500t58$...@Mars.mcs.com>, the code that starts with "(let ((data '((") and let us know what it says.
> 2. References:
> Section 3.2.2.3 Semantic Constraints, says:
> All conforming programs must obey the following constraints, > which are designed to minimize the observable differences > between compiled and interpreted programs: > ... > Special proclamations for dynamic variables must be made in > the compilation environment. Any binding for which there is no > special declaration or proclamation in the compilation environment > is treated by the compiler as a lexical binding.
Looking at that last paragraph, I can see why you came to your conclusion. Taken out of context, you might think that it is a blanket statement about variable access. But there are two details that you are missing.
One is that this paragraph refers to BINDINGS, not to REFERENCES.
The other detail is that you need to interpret your quoted paragraph in the proper context. It is not in the part of the standard that describes variable access rules; it is in the part that describes the compilation environment. This section of the standard is derived from COMPILE-ENVIRONMENT-CONSISTENCY and its purpose is to say that special declarations, when they are meaningful, must be available in the compilation environment (rather than in some other environment) and that they must be available "soon enough" to be used by the compiler. Consider this code snippet:
The purpose of the compilation environment section you quoted is to explain that the above code, although it might work in an interpreted Common Lisp, cannot be compiled. There are two reasons for this: (a) PROCLAIM does not make declarations available in the compilation environment. You need to either enclose it in EVAL-WHEN or change it to DECLAIM. (b) The declaration is not made "soon enough." It must be placed BEFORE the definition of BAR.
Notice I did not say that it has to be placed before the definition of FOO. FOO does not need the declaration, because FOO does not create a binding. FOO's reference to X is automatically special, with or without a declaration.
If you look back at the standard you will notice that the paragraph you omitted (and replaced with three periods) says simply that macros must be defined before they are needed, and that their definitions must be available in the compilation environment. Likewise the other paragraph (which you did not omit) says simply that special declarations must be made before they are needed, and that they must be available in the compilation environment.
The requirement that special variables must be declared applies only in situations where a special declaration is meaningful. In FOO the declaration would be meaningless so the rule does not apply. In BAR the rule applies.
(Once again, it seems, the explanation in CLtL2 is a bit clearer and easier to understand than the newer one in the HyperSpec.) This is the corresponding text from CLtL2 section 25.1.3:
X3J13 voted in June 1989 (COMPILE-ENVIRONMENT-CONSISTENCY) to specify what information must be available at compile time for correct compilation and what need not be available until run time.
The following information must be present in the compile-time environment for a program to be compiled correctly. This information need not also be present in the run-time environment.
In conforming code, macros referenced in the code being compiled must have been previously defined in the compile-time environment. The compiler must treat as a function call any form that is a list whose car is a symbol that does not name a macro or special form. (This implies that setf methods must also be available at compile time.)
In conforming code, proclamations for special variables must be made in the compile-time environment before any bindings of those variables are processed by the compiler. The compiler must treat any binding of an undeclared variable as a lexical binding.
> 3. Outstanding issues:
> I. Once a variable has been declaimed special, how does one make > it unspecial? (Do I need to clarify why I think this is > important?)
When a symbol has been declaimed special, it is special forever. But you can delete the symbol from its package with UNINTERN. Once you have done this, the next time you type the symbol name the reader will create a new (non-special) symbol with the same name. But any data and code that used the old symbol will continue to use the old symbol (until you redefine it and thus pass it through the reader again).
P. S. It is dangerous to proclaim a symbol to be globally special, if its name does not begin and end with an asterisk. After I wrote this article, I tried to connect to the Internet to post it, but I couldn't because my dialing script was broken. Turns out the dialing script uses a lexical variable named X, and this variable was turned special (against its will) by a DECLAIM form that I had evaluated while testing the code example you see above!
Jeff Dalton <j...@cogsci.ed.ac.uk> wrote: > and it's odd that you regard this paragraph of yours as a summary. > It certainly doesn't reflect the discussion *I've* seen.
I think Howard Stearns was just summarizing his own understanding (which turned out to have resulted from misreading the compilation environment rules in the wrong context).
He wasn't attempting to use the word in its more common Usenet sense (a summary of all the discussion in a thread, or of just the parts of the thread that have been accepted by all participants).
# No technical content in this one, just flame-war self defense.
Lately nearly all of your words have been devoted to defending the standard. That is pointless -- I am not challenging the standard, nor is anyone else here. The problem is that your attacks on me have not been consistent with the standard. Why aren't you trying to defend your own articles, rather than the standard itself?
Erik Naggum <e...@naggum.no> wrote: > such behavior reveals an amazingly cavalier attitude to > reproducibility of observations
Reproducibility? In the last ten days you have reproduced against me, in front of the whole world, the same kind of pointless abuse that you must have waged against that other poor guy at some time in the past. Apparently your behavior is VERY reproducible.
> you are in fact wrong on your technical points, Robert Munyer.
Present some evidence, please, or stop saying this.
Haven't you figured out yet that this is how you antagonize people? You repeat (over and over, like a drone) "you are wrong" yet you refuse to present evidence or answer legitimate questions. If this had been a test in school, I would have had to give you an F, because you never even filled in the blanks!
> and it is true, I do treat people who refuse to listen to > authoritative sources and instead go on to ask _people_ what they > think, as fundamentally misguided and extremely unlikely to > produce anything of reasonable value in a discussion, because > they discuss not what is, but what people believe.
I did not ask _people_ what they believe. I asked YOU what you believe, because I was trying to figure out just exactly what it is that you don't understand.
> you said you had a technical argument. I'll believe it when I > see it.
I can't help you if you won't answer my questions. I have asked you many explicit, specific questions in this thread and you have evaded them. Go back and answer them, and then I'll be able to help you clear up your confusion.
In article <500t58$...@Mars.mcs.com> mun...@MCS.COM (Robert Munyer) writes: ># Note to subscribers: this article is long, but it's 99% flame free.
>In article <DwrDLA....@cogsci.ed.ac.uk>, >Jeff Dalton <j...@cogsci.ed.ac.uk> wrote: >> [...] (N.B. special but >> not _proclaimed_ special, an important distinction. Special >> proclamations make all bindings of the name special, declarations don't.) >Based on those last two sentences I think you actually agree with >me, not with Erik.
I do largely agree with you that globals are special/dynamic, but I haven't found anything in the Standard that is as clear as CLtL2 p 70. However, that doesn't seem to be the only issue ...
> Erik's latest attempt at spin control seems to >be a claim that an implementation is allowed (under both CLtL2 and >the ANSI standard) to PROCLAIM a symbol special, if you use SETQ >to give it a global value. I'm not sure if Erik thinks this also >applies to SET and SETF and (SETF SYMBOL-VALUE), because he refuses >to answer my questions.
If the aim is to figure out the truth about Common Lisp, rather than to win over particular individuals, then I don't think it matters whether Eric has changed his position or not, or whatver the "spin control" is about.
Anyway, I haven't looked into the question of whether implementations can proclaim the variable special. I'd regard that as a hostile act in most implementations, because it has a pervasive effect and there's no way to undo it. (And if there is a way to undo it, it will be an implementation-specific way.)
>Remember that in the HyperSpec, the unadorned term "variable" refers >to a binding, not to the symbol that names the binding.
I haven't looked into it in detail, but I'd be careful about concluding that just because it's what the glossary says. In any case, I don't confine my own use of "variable" to that definition.
> I am not >saying that a BINDING can be something other than lexical or constant >or dynamic; I am saying that a NAME can have a lexical binding and >a dynamic binding at the same time --
That much is clearly true; moreover, you should be able to refer to both. For instance:
If you put in special declarations, then I think the Standard is clear, and you can get the "special but not proclaimed special" behaviour for global variables. But without the declarations, what are implementations allowed to do? That's not so clear, and you have to look at lots of stuff: what are conforming implementations allowed to do in various circumstances, and so on.
>That and in fact, that dynamic >binding can be global. If you assign a global value to a variable >name without proclaiming that name to be special, then you can >still have lexical bindings on that same variable name.
>and let us know what it says? The results should be:
> These proclaim special: > DEFPARAMETER > DEFVAR > These do not: > SET > SETF > (SETF SYMBOL-VALUE) > SETQ
In CMU CL 17f, I get:
These proclaim special: defparameter defvar setf setq These do not: set (setf symbol-value)
>In fact, since you've used over a dozen Common Lisps, you probably >have several of them handy. It would be great if you could evaluate >the above code in each of them.
I have only a few of them handy these days. However, both GCL-1.1 and Lucid 4.1 give the result you think they should.
>Also, any implementation which follows Erik's suggestion, and >proclaims symbols special when not explicitly required to by the >standard, will be unable to evaluate standard example code >successfully. For example, see the code in the section on EVAL:
Good point. But I'm not sure examples really count -- I'd have to find what the Spec says about the status of examples.
>> For instance, from PROCLAIM-LEXICAL version 2:
>This PROCLAIM-LEXICAL document to which you refer is very interesting. >This is the first time I've heard that anyone on the committee has >addressed this issue directly. PROCLAIM-LEXICAL is not mentioned >in the standard; does that mean the issue never came to a vote?
It came to a vote; no proposals passed (or at least not any that changed anything). But since this message is already long, and since I'm out of time, I'll respond to your comments on PROCLAIM-LEXICAL in a separate message later on. Meanwhile, I've put some things on the Web that you may find of interest. See http://www.aiai.ed.ac.uk/~jeff/lisp/special.html
In article <3050210651732...@arcana.naggum.no> Erik Naggum <e...@naggum.no> writes: >Robert Munyer, if I ever doubted that you were unreasonable, your last note >has certainly removed any shred of it. it is abundantly clear that your >purpose now is revenge, rather than any purported "technical" issues.
>if you should return to technical discussions, please, try to respect that >those with whom you try to discuss anything technical might want to refer >you to authoritative documents and standards instead of including them in >their replies or paraphrasing them with an added chance of introducing more >confusion.
I didn't see all of the earlier discussion, for various reasons. Could you perhaps say, for me and any others in similar boats, what technical issue is, as you see it. Is it whether globals are special, whether CMU CL is allowed to automatically proclaim variables special, or something else?
>you are in fact wrong on your technical points, Robert Munyer. there is >nothing more than "read the fine manual" to tell you. since you refuse to >do that,
Well, I'll read the manual, if you say what sections you think are relevant.
Unfortunately, my understanding of CL is not based on the Standard but on CLtL I and what happened in X3J13. I assume the Standard reflects the intentions of X3J13 (and that I understand those intentions fairly well), but when it comes to the standard I can seldom find all the relavant sections without a lot of mousing around in the HyperSpec, so it's fairly easy for me to miss something.
| Could you perhaps say, for me and any others in similar boats, what | technical issue is, as you see it.
the initial technical point I made was that Common Lisp does not make the distinction that Robert Munyer said it does in his reply, namely of _treating_ foo special in (defvar foo ...) and _not_ special in (setq foo ...) at top-level. his exact words from <4v7ifq$...@Mars.mcs.com> were as follows:
DEFVAR doesn't just define a global variable X; it also declares that all variables X are "special." A special variable is dynamic rather than lexical, so it bypasses the normal scoping rule. Look what would happen if you used SETQ rather than DEFVAR, to establish a global variable without declaring it to be special:
? (setq x 100) 100 ? (let ((x 1)) (eval 'x)) ;Compiler warnings : ; Unused lexical variable X, in an anonymous lambda form. 100
I pointed out that the semantics of SETQ at top-level without a special declaration is not defined by the language. and the fact remains, it is not defined by the language. implementations are free to do what they want.
| Well, I'll read the manual, if you say what sections you think are | relevant.
in my reply to him in <3049395203874...@arcana.naggum.no>, I wrote:
for more information on the environments in Common Lisp, see the Common Lisp Hyperspec at Harlequin, Inc, section 3.1.1 Introduction to Environments.
after which Robert argued that the HyperSpec was in conflict with CLtL2, that he could change a few words to amend his article, and strongly implied that his purpose was to have _me_ (not the standard, not the language) distinguish between the behavior of SETQ and DEFVAR at top-level, which I had already stated very clearly was not defined by the standard.
res ipsa loquitur.
#\Erik -- main () { printf ("%d\n", sin ("foo")); }
Barry Margolin <bar...@bbnplanet.com> wrote: > > whether the semantics of `setq' at top-level of a variable that > > has not been declared special is defined by Common Lisp. I > > can't see that it is.
> I agree. The standard does not specify these semantics, which > permits implementations to do whatever they want.
I have three quick arguments against the above conclusion. Taken together, I believe they are conclusive and indisputable.
* Claim 1. Use of top-level SETQ to initialize a variable that has not been previously declared special is completely acceptable in a code example, even if it is not something you would do in an actual program.
* Argument 1.1. This usage appears in the standard itself. For example see the section on SETQ:
* Claim 2. It is not acceptable for an implementation to proclaim a symbol special merely because its value is initialized by a top-level SETQ.
* Argument 2.1. Such a proclamation would be a side effect. The standard does not say that this side effect exists or might exist. My understanding is that side effects are not allowed unless the standard permits them explicitly.
If side effects were allowed whenever they are not explicitly forbidden, all hell would break loose. Virtually any construct could produce virtually any side effect, because the standard very rarely states explicitly that a certain construct will not have a certain side effect. Instead, it is taken for granted that only documented side effects can exist.
* Argument 2.2. The standard itself contains code which (like my own 8/18 example) would fail if this proclamation were allowed to occur. Any implementation which produces this undocumented side effect will fail to evaluate successfully the following code example from the standard:
(setq form '(1+ a) a 999) => 999 (eval form) => 1000 (eval 'form) => (1+ A) (let ((a '(this would break if eval used local value))) (eval form)) => 1000
The standard example code above makes it absolutely clear that SETQ does not, and must not, proclaim a symbol to be special.
Erik Naggum <e...@naggum.no> wrote: > [Jeff Dalton]
> | Could you perhaps say, for me and any others in similar boats, > | what technical issue is, as you see it.
> the initial technical point I made was that Common Lisp does not > make the distinction that Robert Munyer said it does in his reply, > namely of _treating_ foo special in (defvar foo ...) and _not_ > special in (setq foo ...) at top-level.
What do you mean by "_treating_ foo special?" Do you mean (a) proclaiming the symbol to be special? Or do you mean (b) placing the new value in a binding that is special? If you answer (a), I will rebut your answer. If you answer (b), I will agree with your answer, but I will rebut any claim that it invalidates my 8/18 code example which you just quoted on 8/30.
> in my reply to him in <3049395203874...@arcana.naggum.no>, I > wrote:
> for more information on the environments in Common Lisp, see > the Common Lisp Hyperspec at Harlequin, Inc, section 3.1.1 > Introduction to Environments.
> after which Robert argued that the HyperSpec was in conflict with > CLtL2,
Only in the details of how the word "variable" is defined, not in the details of the technical question that we are discussing now.
> that he could change a few words to amend his article,
Again, because we were using subtly different definitions of the word "variable." I amended the article to use the definition that can be found in the glossary of the HyperSpec.
> and strongly implied that his purpose was to have _me_ (not the > standard, not the language) distinguish between the behavior of > SETQ and DEFVAR at top-level,
Jeff Dalton <j...@cogsci.ed.ac.uk> wrote: > Anyway, I haven't looked into the question of whether implementations > can proclaim the variable special. I'd regard that as a hostile > act in most implementations, because it has a pervasive effect > and there's no way to undo it. (And if there is a way to undo > it, it will be an implementation-specific way.)
I agree. In fact I'd say this act is not only hostile, but incorrect.
> > These proclaim special: > > DEFPARAMETER > > DEFVAR > > These do not: > > SET > > SETF > > (SETF SYMBOL-VALUE) > > SETQ
> In CMU CL 17f, I get:
> These proclaim special: > defparameter > defvar > setf > setq > These do not: > set > (setf symbol-value)
OK, then I can say unequivocally that CMU CL 17f has a bug (or else it is not really standard Common Lisp). You used the word "hostile" to describe exactly this feature of CMU CL 17f, right? I would go further and use the word "incorrect" or "non-standard."
> > In fact, since you've used over a dozen Common Lisps, you > > probably have several of them handy. It would be great if you > > could evaluate the above code in each of them.
> I have only a few of them handy these days. However, both GCL-1.1 > and Lucid 4.1 give the result you think they should.
As does MCL (2.0.1 and 3.0).
> > Also, any implementation which follows Erik's suggestion, and > > proclaims symbols special when not explicitly required to by the > > standard, will be unable to evaluate standard example code > > successfully. For example, see the code in the section on EVAL:
> Good point. But I'm not sure examples really count -- I'd have > to find what the Spec says about the status of examples.
I certainly hope you don't find anything that says that examples don't "really count." That would be awful. If the committee ever said that everything written in English counts, and everything written in Lisp does not, then they would be putting themselves in the frightful position of having to define and describe a large and complex programming language entirely in English.
English is fuzzy and imprecise; Lisp is not. If you read part of the standard in English, and part of it in Lisp, and you think that the English part says that the Lisp part is wrong, you had better try to re-read the English part and see if there's another way you could possibly interpret it.
In fact, I'd say that's exactly what code examples are for.
Excellent web page! Thank you for making it available (and telling me about it).
Incidentally, David Moon's word "cell" corresponds very closely with the way I used to like to use the word "variable," before I found that doing so could cause so much confusion.
> * (let ((x 1)) (eval 'x)) > Warning: Variable X defined but never used. > Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: > the variable X is unbound.
> This seems counterintuitive to me. Is EVAL just using the global > environment? Is that what the language spec says it should be? > If that is the case, how could the following behaviour be explained:
> * (defvar x 100) > X > * (let ((x 1)) (eval 'x)) > 1 > * x > 100
> Note that the eval only seems to work after a *GLOBAL* variable > 'x' has been defined.
Excerpted from Robert Munyer's 8/18 article <4v7ifq$...@Mars.mcs.com>:
1> DEFVAR doesn't just define a global variable X; it also declares 2> that all variables X are "special." A special variable is dynamic 3> rather than lexical, so it bypasses the normal scoping rule. Look 4> what would happen if you used SETQ rather than DEFVAR, to establish 5> a global variable without declaring it to be special: 6> 7> ? (setq x 100) 8> 100 9> ? (let ((x 1)) (eval 'x)) A> ;Compiler warnings : B> ; Unused lexical variable X, in an anonymous lambda form. C> 100
On 8/19 I suggested changing "it" in line 5 above to "its name." In this amended form, and using the definition of "variable" in the HyperSpec's glossary, the above is correct and expresses the idea that I meant to express.
But if I were answering Mr. Chan's question today, I would write the answer differently so it would be less likely to be misunderstood. I would replace the text in lines 1-5 with something like this:
DEFVAR doesn't just assign a global value to a symbol; it also globally declares that symbol to be "special." This means that from that point onward, all variable bindings and variable references using that symbol will be "special," including for example the binding created by your (LET ((X 1)) ...) form. Special bindings and references are dynamic rather than lexical, so they bypass the normal scoping rule. Look what would happen if you used SETQ rather than DEFVAR, to assign 100 as the global value of X without globally declaring the symbol X to be special:
I would also add a postscript to explain the problem with CMU CL. Something like this:
P. S. At least one implementation (a version of CMU CL) has a non-standard implementation of SETQ and will not produce the correct result in that last example. You can work around the problem in a number of ways. In standard Common Lisp you could use any one of these six forms in that last example:
1. (setq x 100) 2. (setf x 100) 3. (set 'x 100) 4. (setf (symbol-value 'x) 100) 5. (locally (declare (special x)) (setq x 100)) 6. (locally (declare (special x)) (setf x 100))
But in at least one version of CMU CL, you could not use #1 or #2 and would have to choose one of #3 through #6.
In article <3050412036443...@arcana.naggum.no> Erik Naggum <e...@naggum.no> writes: >[Jeff Dalton]
>| Could you perhaps say, for me and any others in similar boats, what >| technical issue is, as you see it.
>the initial technical point I made was that Common Lisp does not make the >distinction that Robert Munyer said it does in his reply, namely of >_treating_ foo special in (defvar foo ...) and _not_ special in (setq foo >...) at top-level. his exact words from <4v7ifq$...@Mars.mcs.com> were as >follows:
> DEFVAR doesn't just define a global variable X; it also declares > that all variables X are "special." A special variable is dynamic > rather than lexical, so it bypasses the normal scoping rule. Look > what would happen if you used SETQ rather than DEFVAR, to establish > a global variable without declaring it to be special:
There are problems with how RM's point was worded above, but I think some of the things he said later made it clearer what he was getting at. And he's at least partly right. (DEFVAR X ...) proclaims X special, which affects all uses (reference, assignment, binding) of X as a variable -- the `all variables X are "special"' above -- and you can avoid this pervasive effect by not using DEFVAR.
>I pointed out that the semantics of SETQ at top-level without a special >declaration is not defined by the language. and the fact remains, it is >not defined by the language. implementations are free to do what they >want.
Could you say _why_ you think the semantics is not defined and why that leaves implementations free to do whatever they want? For instance, if the standard explicitly said "the consquences are undefined", or used one of the other phrases defined in the dection on error terminology, that would make things fairly clear.
But it looks instead like (at most) the standard merely fails to state the semantics, and I don't know where it says what implementations can do in such cases.
There are also a number of things in the standard that suggest that the semantics of top-level SETQ is defined, so that any failure to explicitly and clearly define it is an oversight. (I've discussed some of these in earlier articles and won't repeat the discussion here.)
(Note for RM: the standard explicitly says that "Examples" sections are not part of the standard.)