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

From: Drew Adams <[email-masked]>
Date: Sun, 19 Apr 2020 15:24:24 -0700 (PDT)

> >> distinguish between constant objects (which the
> >> program should not change) and mutable objects
> >> (which the program can change).
> >
> > That's just not what "constant" means.
> 
> What does "constant" mean to you? It's not clear.

Something that remains constant.  You simply can't
change it - impossible.

The doc for `defconst' makes clear that it does _not_
define a constant, for example.  In what way is what
it defines a variable and not a constant?  The fact
that you _can_ change it.  If you can change something
then it's not a constant.

The problem is that you're using "constant", NOT for
something that CANNOT be changed, but for something
that you SHOULD NOT try to change.  Not the same thing.

> > And I suspect that your _uses_ of _not_ "mutable"
> > will still be for things that we really want to say
> > you probably _should not_ change, and not that
> > you _cannot_ change them.
> 
> Your suspicion is correct.

So my suspicion is correct: you're misusing "not
mutable" to mean, not something that can't be
changed but something that probably shouldn't be
changed.  See above: not mutable = constant.

> In the current emacs-27 documentation, "mutable"
> means you can change the object,

That contradicts your statement of my suspicion
being correct.  If "mutable" means you can change
it (which is truly what it means) then "not mutable"
means you can't change it.  It doesn't mean only
that you probably shouldn't change it.

It's the same point.  mutable = changeable,
not mutable = constant (not changeable).

You're using "should not" in place of "cannot".
Which means you're also using "no reason not to"
in place of "can".

And the gotcha is precisely that in some cases
where you _can_, you probably _should not_.

> "constant" means you should not change it.

Again, a misuse.  "Constant" means truly not mutable,
i.e., you _cannot_ change it.

The message you're giving is backward, or at least
unclear.

Don't say "constant".  Say "don't try to change it".

Not because you can't change it (not because it's
constant), but because the code won't necessarily
do what you expect - it might change as you think,
or it might not.  That's really the point, I think.

> It's intended to be documentation that is simple
> and consistent

IMO, it's neither.  Simple is to just say that you
_cannot depend on_ `quote' (and some other constructs,
no doubt) returning a new object, especially in code
that looks like it would be evaluated multiple times.

And since you can't depend on this, don't.  That's
the simple message: "don't do that, because it might
not do what you expect" (when byte-compiled, in
particular).

It might (IMO) be helpful to explain that for
interpreted Elisp source code what you see is what
you get (is that always true?), but the same is not
true for byte-compiled code.  And `(quote (A B))'
is a good example.

We probably already say something like that (?) in
other contexts: byte-compiled code may change order
of evaluation or the number of times a subexpression
gets evaluated - for optimization.  You can't count
on byte-code acting just like as source code from
which it's compiled would suggest.

> what they shouldn't do (try to change a constant)

No one tries to change a constant.  The problem -
the gotcha - is that it's not always obvious when
your code is trying to change a constant.  In
particular (but not only), beware of quoted lists.

> Of course the documentation could have a more-complex
> discussion of the various ways that an object could
> be "constant".

And somewhere in the doc that might be helpful, but
only if the particular cases documented are cases we
intend to keep as such.  It can happen that we instead
decide to keep that in the dark ("just" implementation),
and we just document that whether XYZ is such a case is
"undefined" - so don't count on it acting as a constant
or not as a constant.

> The object could be in read-only memory enforced by
> the hardware and operating system,

As I said earlier, there's no need to say something's
a constant if it's actually enforced as a constant,
in the sense that an error is raised if you try to
modify it.

The only cases that are problematic are those where
you can think your code modifies something (anew)
when in fact it might not.  That's the case we're
talking about wrt quoted list structure. 

> > And places where you will likely say there's no
> > reason you _shouldn't_ change something will
> > likely give the impression that this is because
> > it is "mutable", and give the impression that
> > there's no reason you shouldn't change anything
> > that you _can_ change.  This can give the
> > impression  that if you _can_ change something
> > (the real meaning of "mutable") then there's no
> > reason you shouldn't change it.
> 
> I'm not following.

By mischaracterizing not mutable as "should not be
changed" (instead of "cannot be changed"), you can
give the false impression that the opposite is true:
if something is mutable then there's no reason you
shouldn't change it.

Not that the latter follows logically from the former,
but by twisting the meaning of "mutable" all bets in
understanding are off.