Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!decwrl!shelby!agate!bionet!arisia!roo!masinter From: masinter@parc.xerox.com (Larry Masinter) Newsgroups: comp.lang.lisp Subject: Re: Constants in code (Ex- Virtues of Lisp syntax) Message-ID: Date: 4 Oct 90 06:47:15 GMT References: <2863191137@ARTEMIS.cam.nist.gov> <1990Sep24.162735.13243@hellgate.utah.edu> Sender: news@parc.xerox.com Organization: Xerox PARC, Palo Alto, CA Lines: 97 In-reply-to: various messages Many quotes ago I wrote something about: >> > (let ((var '(a b c))) >> > ... >> > (nconc var value)) >> ... This certainly isn't legal Common Lisp, and I didn't mean to imply that it is. What I was trying to say was just that every Lisp programmer will eventually stumble on a *bug* of this form and be baffled by it. If you wanted to do something like this actually you'd write (defvar *values* (list 'a 'b 'c)) and then nconc *values* away. Somebody else wrote: >If you WANT the permanent change then you should presumably write >(let ((var '(a b c))) > (defun foo (..) > .. (nconc var value))) >to make clear the extent of var. This is also illegal. I think in X3J13 we struggled a lot with the wording to try to rule out the 'obvious' illegal situations. It was hard. Gumby (I think) wrote: >> Anyway, the capability to side-effect constants in storage was not >> removed for taste reasons, but efficiency; it permits me as a lisp >> implementor to place code into read-only storage (and possibly share >> it among processes). I personally didn't think the issue was either taste or efficiency. In general, I never saw that X3J13 declaring something "is an error" in Common Lisp as an act of "removing" a capability, but rather of just documenting a way in which program behavior was bound to be unpredictable. I think the main problem is that you cannot even talk about the semantics of code that modifies itself or its lexical constants using the language in which Common Lisp is described. It would be unreasonable to require implementations to *signal* an error when constants were modified because it would *require* all implementations to store such constants in read-only storage and trap attempts to modify them. In some posting, Gumby said: >I would be unhappy if quote performed computation each time you used >it! A very common idiom is to pass a quoted, uninterned symbol around >as a marker in some structure. (I used to use '(())). This is the >only way I can get a token I guarantee won't appear in my input >stream! You have to be very careful here. I remember the debate, but not the resolution, but I believe, is that it is possible that a compiler (or interpreter or whatever makes your Common Lisp run) may also collapse EQUAL, quoted structures, e.g., (let ((x '(())) (y '(()))) (eq x y)) might be true, and, furthermore, the '(()) might even be collapsed with some other unrelated lexical occurrence of a quoted structure. (E.g., one used by READ). Thus, if you want a token that will not occur in your input stream, you should probably do: (defconst *end-of-stream* (list nil)) and then use *end-of-stream* wherever you want a marker. I think this is better style, in any case, and hardly less efficient. -- Larry Masinter (masinter@parc.xerox.com) Xerox Palo Alto Research Center (PARC) 3333 Coyote Hill Road; Palo Alto, CA USA 94304 Fax: (415) 494-4333