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

From: Drew Adams <[email-masked]>
Date: Tue, 28 Apr 2020 21:36:31 -0700 (PDT)

> > You're _not_ using the language that's used
> > for Common Lisp.
> 
> In what sense does the language differ? Here's
> a quote from CLtL2 (page 115):
> 
> "it is an error to destructively modify any object that appears as a
> constant in executable code, whether within a 'quote' special form or as
> a self-evaluating form."
> 
> This use of the word "constant" is consistent
> with what's in the emacs-27 doc.

I quoted that same text as part of a proposal to
FIX the very gotcha that Elisp still suffers from.

I already addressed this, specifically.

See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=40671#24

I specifically spoke of CLTL1, because its state,
and the state of CL at that time corresponds more
closely with that of Elisp and its doc, since CLTL1
predates the proposal to handle the gotcha
systematically.

> > Elisp corresponds to the behavior of CLTL1 in
> > this regard, not to any later update
> 
> Those older CLtL semantics were not well-defined,

Precisely the problem Emacs Lisp has!  And not
just not well defined.  Different behavior
sometimes between interpreted and compiled code.

That IS the gotcha - the fact that Elisp does NOT
raise an error systematically in all such cases.
It does NOT always prevent you from modifying a
constant, quoted list etc.

Elisp is like CL was BEFORE the proposal I quoted,
which was adopted as the CLTL2 text you quoted.

They fixed the problem for CL by redefining CL
to not have it.  For an implementation of CL to
follow the updated definition, it must provide
consistent behavior, preventing modification of
constants, quoted lists, etc.

Sound familiar yet?

> and to the extent that they were defined were not
> followed by Common Lisp implementations. It's not
> clear that the emacs-27 Elisp implementation
> corresponds to those older semantics, and it's
> also not clear that documenting CLtL1 semantics
> would be a good idea for Elisp.

The point is that the problem they fixed is the
problem Elisp still has.  Whether it is exactly
the same in all particulars is unimportant -
it's about the behavior being undefined and not
necessarily the same if interpreted or compiled.

I mentioned the CL proposal, to take effect
for CLTL2, quoting:

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

Why "clarify"?  Because it was NOT stated as
part of the previous definition of CL that
that is an error.  And that meant that CL
implementations were NOT required to
systematically raise an error to enforce that.
They did NOT always prevent you from modifying
such thingies.

The proposal also said:

 "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."

That was the problem to be fixed, by raising an
error, i.e., by disallowing, in practice.  And
that's exactly the problem that Elisp still has:
it does NOT disallow (systematic error).  And no
amount of saying that it does (claiming you
"cannot" do it) changes that fact.

I quoted CLTL about the behavior before the
proposal, i.e., before systematically raising
an error:

 "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."

And about that I said:

  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.

That's precisely the point.  We do NOT disallow.
We do NOT always raise an error.  We do NOT
always PREVENT changing quoted list structure etc.

AND SO we should NOT tell users that they CANNOT
do so - sometimes they CAN.  We should instead
tell them that they SHOULD NOT try to do so, and
if they do then the resulting behavior is undefined.
___

I said last message that I gave up.  And now I'm
literally repeating what I wrote 10 days ago.
You haven't heard, or you're not listening.  (And
my impression is that others have said the same as
I, or similar.)  Sorry, I'm done.