>>>>> "Erik" == Erik Naggum <e...@naggum.no> writes:
Erik> This is just plain false.
I was thinking only of the top-level, and in my eagerness to post (since I enjoy trying to be helpful), I was a dumb-ass and forgot about lexical bindings. Unless SYMBOL-VALUE and the top-level symbol binding are different things, so if I'm still confused about this issue, please correct me.
-- "I will never submit to your lustful advances", cried Princess Beatrice, as the wealthy, powerful, muscular and strikingly handsome Count Bertrand slowly adjusted his mink gloves, "at least for another half-hour!" --Dr. Zinn, from the novel
In article <39499071.82DDC...@pacbell.net>, s...@alum.mit.edu wrote: >Erik Naggum wrote:
>> * sash...@vuse.vanderbilt.edu (Sashank Varma) >> | since SETF is a macro, it has to expand into an expression. >> | i assume that implementations ensure that this expansion is >> | pure ANSI CL; this may even be mandated in the standard.
>> Why do you assume that? Why should it be mandated?
thankfully i've been saved from publicly fumbling too much around an incorrect assumption.
[snip]
>BUT any such implementation-specific mechanism _must_ be (or eventually >macroexpand into) a call to an implementation function. No implementation >setf expansion, nor for that matter any other standard macro, may expand >into a nonstandard special form. To do so would make it impossible for >portable code walkers to work, and that would be a bad thing.
[snip]
you nailed the thing that was bugging me -- could program-analyzing programs work across implementations if ansi cl macros are allowed to expand into implementation-specific "mechanisms"? the answer, as i now see, is "of course" -- provided those mechanisms bottom-out as function calls or ansi-cl-specified special operators.
* sash...@vuse.vanderbilt.edu (Sashank Varma) | since SETF is a macro, it has to expand into an expression. | i assume that implementations ensure that this expansion is | pure ANSI CL; this may even be mandated in the standard.
Why do you assume that? Why should it be mandated?
| one way that i could be wrong is that it could be perfectly legal | for SETF to macroexpand into implementation-specific mechanisms for | modifying bindings, but this just seems wrong.
Could you elaborate on why you think this way?
#:Erik -- If this is not what you expected, please alter your expectations.
* Barry Margolin <bar...@genuity.net> | Assumptions don't have reasons.
Sigh. "Why" does not only refer to reasons, regardless of the truth of your statement, but to any cause, as in "how come". Perhaps your assumptions are causeless and entirely random, but this is not a universal truth.
#:Erik -- If this is not what you expected, please alter your expectations.
In article <39499071.82DDC...@pacbell.net>, Steven M. Haflich <s...@alum.mit.edu> wrote:
>Compilers are free to treat additional operators as special forms, but >they must provide real macro or function versions for benefit of other >code walkers that they themselves may ignore in favor of some semantically >equivalent special form.
While this is a good idea, and I even think there was some discussion of the issue in X3J13, did we actually put anything into the standard that specifies it? It says that there's no way for the *user* to define new special operators, but doesn't say that the implementor can't build in more (and even the clause that says that there's no way for the user to define them presumably means that there's no *standard* way to do so -- it can't stop the implementor from providing an extension that the user could invoke). It also says that any macro operator can be implemented as a special operator as long as the macro definition is still there, but that's not talking about new special operators that the implementation defines (I think it's actually referring to the operators that the standard says are macros).
The problem with saying that all implementation-defined special operators have to have macro definitions as well is what the macro could expand into? The implementation presumably defined these special operators because they do something that can't be done using macros or functions (I'm ignoring operators implemented specially just for optimization reasons); for instance, suppose the CL designers had decided not to include TAGBODY and GO in the language, but a vendor wanted to provide a Maclisp-compatible version of PROG that included these features -- what would they expand into? The SPECIAL-OPERATOR-P function is provided so that code walkers can notice when they've stumbled onto implementation-dependent special forms; if they don't know how to handle that special form, they can punt and report the failure to the user.
-- Barry Margolin, bar...@genuity.net Genuity, Burlington, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
> In article <39499071.82DDC...@pacbell.net>, > Steven M. Haflich <s...@alum.mit.edu> wrote: > >Compilers are free to treat additional operators as special forms, but > >they must provide real macro or function versions for benefit of other > >code walkers that they themselves may ignore in favor of some semantically > >equivalent special form.
> While this is a good idea, and I even think there was some discussion of > the issue in X3J13, did we actually put anything into the standard that > specifies it? It says that there's no way for the *user* to define new > special operators, but doesn't say that the implementor can't build in more > (and even the clause that says that there's no way for the user to define > them presumably means that there's no *standard* way to do so -- it can't > stop the implementor from providing an extension that the user could > invoke).
An implementation may have extensions, to be sure, but as soon as one is invoked the resulting world _might_ no longer be ANS conformant. But in any case, this is what the ANS says:
3.1.2.1.2.1 The set of special operator names is fixed in Common Lisp; no way is provided for the user to define a special operator. The next figure lists all of the Common Lisp symbols that have definitions as special operators.
26.1.19 special operator: n. one of a fixed set of symbols, enumerated in Figure 3.1.2.1.2.1 Special Forms, that may appear in the car of a form in order to identify the form as a special form.
> It also says that any macro operator can be implemented as a > special operator as long as the macro definition is still there, but that's > not talking about new special operators that the implementation defines (I > think it's actually referring to the operators that the standard says are > macros).
I take this to mean that the compiler does not need to use the macroexpansion if for some reason it wants to use the special form. One such example in ACL is the treatment of a top-level defun. The file compiler recognizes these and generates various load-time effects in a way more efficient than what the macroexpansion would generate. (Compiled files are smaller and load faster.) But the observed effects are very carefully kept equivalent, and I personally placed strong comments in the code warning future developers to keep things that way.
> The problem with saying that all implementation-defined special operators > have to have macro definitions as well is what the macro could expand into? > The implementation presumably defined these special operators because they > do something that can't be done using macros or functions (I'm ignoring > operators implemented specially just for optimization reasons); for > instance, suppose the CL designers had decided not to include TAGBODY and > GO in the language, but a vendor wanted to provide a Maclisp-compatible > version of PROG that included these features -- what would they expand > into?
I could still implement it grotesquely (and inefficiently, but not grossly so) using catch/throw, case, and tail-position call elimination. I _think_ it can be done without dependency on tail-call elimination, but I'm too lazy to think though the implementation right now.
> The SPECIAL-OPERATOR-P function is provided so that code walkers can > notice when they've stumbled onto implementation-dependent special forms; > if they don't know how to handle that special form, they can punt and > report the failure to the user.
But that would mean that no code could depend upon the success of a code walker. That seems a poor design, similar to C++. The reason Lisp has code walkers is so tools that were not designed to interoperate can still do so. The Java VM tries to accomplish this with load/run time mechanisms. Lisp accomplishes this at compile/load/run time. The purposes and tradeoffs are different.