Paul wrote:tayssir wrote:
- Code: Select all
CL-USER> (defvar *foo*
'((:a . 1)
(:b . 2)))
;; “I just sensed a glitch in the Matrix.”
It's undefined to destructively modify "literals" like quoted lists.
Judging by the prompt in front, your "literal" was defined at the REPL, so it's perfectly well defined, but in any case, how would that be "an inconsistency"?
The spec contradicts this claim, and Kent Pitman (hyperspec author extraordinare) cites fairly nasty consequences — even at the REPL.
This common misconception is instructive: we see inconsistencies in CL's spec even where there are none. (In this case, special-casing of the REPL.) This is not unlike the situation that many of us have probably been in (I hope I'm not the only one), where we're wrestling with some difficult-to-install library, and come to blame the library even in particular moments when we happen to be at fault.
Note that Kent was replying to a lisp implementor (Roger Corman) who just goofed up on this point. (So there's no shame in that.) Elsewhere in the thread, you'll find another implementor (Duane Rettig of Franz) share his own war-stories of discovering that Franz software had similar bugs due to modifying literals, which he claimed nearly led to more years of hard-to-reproduce bugs.
The reader must generate a new list when it reads the form in, and QUOTE just returns the identical list that is its argument, therefore it returns the fresh list constructed by the reader; there's no way to tell the difference between that list and one constructed with LIST, therefore there's no way mutating it can have any different effect than if you had used LIST. So either all list mutations are undefined, or this one isn't (or Lisp is magical).
As Kent cited, simple optimizations can defeat that, REPL or no. Implementations like MCL can decide to share quoted literals throughout the program, put them in read-only spaces, etc.
And if Kent and the spec are wrong, the resulting inconsistency would only provide more lurid evidence of CL's inconsistency.