GNU bug report logs -
#40671
[DOC] modify literal objects
Previous Next
Full log
Message #81 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 5:53 PM, Michael Heerdegen wrote:
> Paul Eggert <eggert <at> cs.ucla.edu> writes:
>
>>> (let ((l (list 1 2 3)))
>>> `',l)
>>> ==> '(1 2 3)
>>> If you evaluate this (the return value is a valid expression),
>>> `quote'
>>> returns a list, but it's not a list literal.
>>
>> Sure, but one shouldn't be modifying that list. Once you hand a Lisp
>> object to 'eval', modifying that object later ought to be a no-no even
>> if the interpreter happens to do something non-crashy now.
>
> But I can modify the list before handing it over to `eval',
> e.g. replacing the `1' with `cons'.
Yes, that's fine. You can modify the list *before* handing it to eval, but it
should be off limits afterwards. That is, the manual doesn't say or imply that
the `,l yields a constant, so the result of the `,l is still modifiable. But
once you hand the list off to eval, watch out: you shouldn't modify it.
Another way to put it is: an object can start off mutable and later become
constant when you start using it as part of a program. Come to think of it,
perhaps this should be added to the Constants and Mutability section. Something
like the following patch, perhaps.
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index abd258eb53..dd7eaf5ae4 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -2400,6 +2400,11 @@ Constants and Mutability
call @code{(make-string 3 ?a)} yields a mutable string that can be
changed via later calls to @code{aset}.
+ A mutable object can become constant if it is passed to the
+@code{eval} function, because you should not modify an object that is
+being or might be executed. The reverse does not occur: constant
+objects should stay constant.
+
Trying to modify a constant variable signals an error
(@pxref{Constant Variables}).
A program should not attempt to modify other types of constants because the
> And even when I eval the original list, I get just the same l as before:
It's OK that the interpreter does that. But you shouldn't *modify* the original
list after handing it off to eval; it might work and it might not. You shouldn't
even rely on the interpreter giving you the same l as before, for that matter;
that's an implementation detail that is not documented and should not be
documented, any more than we should document the fact that (let ((x (cos 1.5)))
(eq x (+ x))) returns t in Emacs 27.
> We must distinguish between the objects created when a program is
> read/compiled, i.e. the objects a program consists of (data and programs
> are the same in Lisp, etc.), and the objects that that program actually
> handles when it runs.
Yes, and the basic idea is that one cannot reliably modify the objects that a
program consists of while running the program; it's not safe. (All we need to do
is to word this correctly and clearly. :-)
This bug report was last modified 5 years and 2 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.