Subject: bug#40671: [DOC] modify literal objects

From: Drew Adams <[email-masked]>
Date: Sat, 18 Apr 2020 14:54:32 -0700 (PDT)

OK, here's a nitpick, FWIW.
___

You say things such as this:

"should be applied only to @dfn{mutable} lists,
that is, lists constructed via @code{cons},
@code{list} or similar operations."

That's not a usual meaning of "mutable".  Your
"that is" makes clear what you mean, sort of, I
suppose.  That part is clear enough, but it's
not a good "definition" of "mutable".

It's about code that always creates new list
structure, versus code that might create new
list structure only sometimes (e.g. the first
time it's encountered).

A quoted list, which you call "constant", is in
fact mutable in some contexts.

An immutable list would be one you couldn't ever
change - it would truly be a constant.  That can
be true for the result of byte-compiling a quoted
list.

But it's not true in general for interpreted
code.  E.g., this example in (elisp) `Setcdr':

  (setq x '(1 2 3))  ⇒ (1 2 3)
  (setcdr x '(4))    ⇒ (4)
  x                  ⇒ (1 4)

What you're really trying to convey presumably
is not that one CANNOT ever modify such a list,
but that one SHOULD NOT modify such a list (e.g.
because of what can happen to it with the byte
compiler).  That's something different, and I
don't think the message comes across well.

Similarly:

"However, the other arguments (all but the last)
must be mutable lists."

"MUST" means you CANNOT do otherwise.  Trying to
do so might result in an error being raised, for
example.  And that's not always the case.  Hence
the gotcha, hence the need for a guideline: Don't
do it; just say no.

That text with "must" is immediately followed by:

"A common pitfall is to use a quoted constant list..."

And _that's_ the point.  But together with your
text saying you CANNOT modify it anyway, things
get confusing.  Modifying a quoted list is
problematic, a gotcha, a pitfall, something to
avoid.

You SHOULD NOT do it precisely because you CAN
do it sometimes.  If you couldn't, e.g., if you
were prevented from doing it by always raising
an error, then there would be no gotcha, no
reason to tell you not to do it.

Anyway, you get the idea.

BTW, "a quoted constant list" is a bit poorly
worded, as well.  (Yes, that text was already
there.)  The problem is using a quoted list
sexp, which can have the effect of producing
a constant list.  It's not about quoting a
list that is somehow already a constant.
Quoting can _produce_ a constant.

---

FWIW, Common Lisp doesn't talk about mutable
or immutable lists (or other objects): 

 "The consequences are undefined if literal
  objects (including quoted objects) are
  destructively modified."

Undefined.  They CAN sometimes be destructively
modified.

And a proposal says to:

 "clarify that it is an error to destructively
  modify objects which are self-evaluating
  forms or which appear inside of a QUOTE
  special form."

And it talks of:

 "modifying quoted data structures"

Such wording makes clear which things we're
talking about.

Cltl says only:

 "implicit sharing of compiled data structures
  may result in unpredictable behavior if
  destructive operations are performed. However,
  CLtL does not explicitly allow or disallow
  destructive operations on constants."

Unpredictable behavior.  It doesn't say it's
always impossible to modify such things.  It
says, in effect, don't try.

That's what we should say for Emacs Lisp, since
we do NOT "disallow modification of constants
consistently in all situations."

For Emacs Lisp this is a gotcha, so we need a
SHOULD.  If it were enforced as a MUST then we
wouldn't need such a caveat.

This was proposed for CL:

 "Disallowing modification of constants
  consistently in all situations, rather than
  just in compiled code, is proposed because in
  some compiled-only situations it may be
  difficult to distinguish between "compiled"
  and "interpreted" code."

Whether "disallow" means raise an error in all
such cases (which was proposed for Cltl) or
just warn users not to do it and say the behavior
is "undefined" (what Cltl did, and what Emacs
should do), is a separate question.

The point about trying to modify a quoted list,
for Emacs Lisp, is this:

Don't do it.  Don't assume that you get new
list structure each time it looks like a quoted
list will be evaluated anew.  It might be
evaluated only once, and the result used as a
constant thereafter.

http://clhs.lisp.se/Issues/iss083_w.htm