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

From: Dmitry Gutov <[email-masked]>
Date: Tue, 5 May 2020 04:39:39 +0300

On 04.05.2020 20:52, Paul Eggert wrote:
> Pretty much any ordinary cons will do.  In (let ((x (cons 0 0))) (setcar x 1)),
> for example, the cons is referenced from executable code but it's OK to modify
> the cons. The cons becomes unreachable when the 'let' finishes. The cons is not
> part of any expression that is evaluated.

But, I mean, if we just make it a literal:

(let ((x '(0 . 0))) (setcar x 1))

...it also becomes okay to modify it because the cons becomes 
unreachable right away. Even so, we strongly recommend against this in 
the manual now.

When the form above is a part of a function body, however, then it's 
*really* inadvisable to use the latter option.

> The problem here evidently is one of terminology, not of understanding the
> underlying issues. When I read "Objects referenced from executable code" I
> evidently got a different meaning than what you intended. These things happen
> when introducing a new terminology.

I have asked for clarification to try to come up with better phrasing. 
But to be frank it's not so important to me as fixing the existing one. 
So if you can find a better option, please be my guest.

In the meantime, what do you think about the attached patch?
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index ea16d9ef15..46462162ca 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -7317,8 +7317,6 @@ setcar
 works is to experiment.  We will start with the @code{setcar} function.
 
 @need 1200
-@cindex constant lists
-@cindex mutable lists
 First, we can make a list and then set the value of a variable to the
 list, using the @code{setq} special form.  Because we intend to use
 @code{setcar} to change the list, this @code{setq} should not use the
@@ -7327,8 +7325,7 @@ setcar
 tried to change part of the program while running it.  Generally
 speaking an Emacs Lisp program's components should be constant (or
 unchanged) while the program is running.  So we instead construct an
-animal list that is @dfn{mutable} (or changeable) by using the
-@code{list} function, as follows:
+animal list by using the @code{list} function, as follows:
 
 @smallexample
 (setq animals (list 'antelope 'giraffe 'lion 'tiger))
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index bba1b63115..8abdd6663f 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -297,7 +297,7 @@ Top
 * Circular Objects::        Read syntax for circular structure.
 * Type Predicates::         Tests related to types.
 * Equality Predicates::     Tests of equality between any two objects.
-* Constants and Mutability::  Whether an object's value can change.
+* Dangerous Mutations::     Objects which should not be modified.
 
 Programming Types
 
diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi
index baddce4d9c..786c2f2de4 100644
--- a/doc/lispref/eval.texi
+++ b/doc/lispref/eval.texi
@@ -158,11 +158,12 @@ Self-Evaluating Forms
 @end group
 @end example
 
-  A self-evaluating form yields constant conses, vectors and strings, and you
-should not attempt to modify their contents via @code{setcar}, @code{aset} or
-similar operations.  The Lisp interpreter might unify the constants
-yielded by your program's self-evaluating forms, so that these
-constants might share structure.  @xref{Constants and Mutability}.
+  A self-evaluating form yields a value that becomes part of the
+program, and you should not attempt to modify their contents via
+@code{setcar}, @code{aset} or similar operations.  The Lisp
+interpreter might unify the constants yielded by your program's
+self-evaluating forms, so that these constants might share structure.
+@xref{Dangerous Mutations}.
 
   It is common to write numbers, characters, strings, and even vectors
 in Lisp code, taking advantage of the fact that they self-evaluate.
@@ -564,8 +565,6 @@ Quoting
 
 @defspec quote object
 This special form returns @var{object}, without evaluating it.
-The returned value is a constant, and should not be modified.
-@xref{Constants and Mutability}.
 @end defspec
 
 @cindex @samp{'} for quoting
@@ -608,9 +607,9 @@ Quoting
 
   Although the expressions @code{(list '+ 1 2)} and @code{'(+ 1 2)}
 both yield lists equal to @code{(+ 1 2)}, the former yields a
-freshly-minted mutable list whereas the latter yields a constant list
-built from conses that may be shared with other constants.
-@xref{Constants and Mutability}.
+freshly-minted new list whereas the latter yields a list
+built from conses that may be shared with other values.
+@xref{Self-Evaluating Forms}.
 
   Other quoting constructs include @code{function} (@pxref{Anonymous
 Functions}), which causes an anonymous lambda expression written in Lisp
@@ -710,7 +709,7 @@ Backquote
 @end example
 
 If a subexpression of a backquote construct has no substitutions or
-splices, it acts like @code{quote} in that it yields constant conses,
+splices, it acts like @code{quote} in that it yields conses,
 vectors and strings that should not be modified.
 
 @node Eval
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index fcaf4386b1..065853042a 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -866,15 +866,14 @@ List Variables
 @node Modifying Lists
 @section Modifying Existing List Structure
 @cindex destructive list operations
-@cindex mutable lists
 
   You can modify the @sc{car} and @sc{cdr} contents of a cons cell with the
 primitives @code{setcar} and @code{setcdr}.  These are destructive
 operations because they change existing list structure.
-Destructive operations should be applied only to mutable lists,
-that is, lists constructed via @code{cons}, @code{list} or similar
-operations.  Lists created by quoting are constants and should not be
-changed by destructive operations.  @xref{Constants and Mutability}.
+Destructive operations should be applied only to lists constructed via
+@code{cons}, @code{list} or similar operations.  Lists created by
+quoting are part of the program and should not be changed by destructive
+operations.  @xref{Dangerous Mutations}.
 
 @cindex CL note---@code{rplaca} vs @code{setcar}
 @quotation
@@ -911,7 +910,7 @@ Setcar
 
 @example
 @group
-(setq x (list 1 2))  ; @r{Create a mutable list.}
+(setq x (list 1 2))
      @result{} (1 2)
 @end group
 @group
@@ -931,7 +930,7 @@ Setcar
 
 @example
 @group
-;; @r{Create two mutable lists that are partly shared.}
+;; @r{Create two lists that are partly shared.}
 (setq x1 (list 'a 'b 'c))
      @result{} (a b c)
 (setq x2 (cons 'z (cdr x1)))
@@ -1022,11 +1021,11 @@ Setcdr
 
 @example
 @group
-(setq x (list 1 2 3))  ; @r{Create a mutable list.}
+(setq x (list 1 2 3))
      @result{} (1 2 3)
 @end group
 @group
-(setcdr x '(4))  ; @r{Modify the list's tail to be a constant list.}
+(setcdr x '(4))
      @result{} (4)
 @end group
 @group
@@ -1135,11 +1134,11 @@ Rearrangement
 
 @example
 @group
-(setq x (list 1 2 3))  ; @r{Create a mutable list.}
+(setq x (list 1 2 3))
      @result{} (1 2 3)
 @end group
 @group
-(nconc x '(4 5))  ; @r{Modify the list's tail to be a constant list.}
+(nconc x '(4 5))
      @result{} (1 2 3 4 5)
 @end group
 @group
@@ -1168,7 +1167,7 @@ Rearrangement
 @end group
 @end example
 
-However, the other arguments (all but the last) should be mutable lists.
+However, the other arguments (all but the last) must be lists.
 
 A common pitfall is to use a constant list as a non-last
 argument to @code{nconc}.  If you do this, the resulting behavior
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 1d5b2c690f..9fdcb4b1bc 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -46,10 +46,6 @@ Lisp Data Types
 Lisp variables can only take on values of a certain type.
 @xref{Variables with Restricted Values}.)
 
-  Some Lisp objects are @dfn{constant}: their values should never change.
-Others are @dfn{mutable}: their values can be changed via destructive
-operations that involve side effects.
-
   This chapter describes the purpose, printed representation, and read
 syntax of each of the standard types in GNU Emacs Lisp.  Details on how
 to use these types can be found in later chapters.
@@ -63,7 +59,7 @@ Lisp Data Types
 * Circular Objects::            Read syntax for circular structure.
 * Type Predicates::             Tests related to types.
 * Equality Predicates::         Tests of equality between any two objects.
-* Constants and Mutability::    Whether an object's value can change.
+* Dangerous Mutations::         Objects which should not be modified.
 @end menu
 
 @node Printed Representation
@@ -2379,51 +2375,34 @@ Equality Predicates
 @end example
 @end defun
 
-@node Constants and Mutability
-@section Constants and Mutability
-@cindex constants
-@cindex mutable objects
-
-  Some Lisp objects are constant: their values should never change
-during a single execution of Emacs running well-behaved Lisp code.
-For example, you can create a new integer by calculating one, but you
-cannot modify the value of an existing integer.
-
-  Other Lisp objects are mutable: it is safe to change their values
-via destructive operations involving side effects.  For example, an
-existing marker can be changed by moving the marker to point to
-somewhere else.
+@node Dangerous Mutations
+@section Dangerous Mutations
 
-  Although all numbers are constants and all markers are
-mutable, some types contain both constant and mutable members.  These
-types include conses, vectors, strings, and symbols.  For example, the string
-literal @code{"aaa"} yields a constant string, whereas the function
-call @code{(make-string 3 ?a)} yields a mutable string that can be
-changed via later calls to @code{aset}.
+  Most Lisp programs first create some values, then mutate them.  For
+this to work well, a new value should generally be created every time
+a function is called.  When a value is created using a function such
+as @code{list}, @code{cons}, @code{make-string} or
+@code{copy-sequence}, that happens reliably, and such a value is safe
+to modify.
 
-  A mutable object can become constant if it is part of an expression
-that is evaluated.  The reverse does not occur: constant objects
-should stay constant.
+  Modifying the values obtained by evaluating a self-evaluating form
+(such as @code{"abc"}) is not advised.  Values that appear as part of
+a program should not be modified.
 
   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
-resulting behavior is undefined: the Lisp interpreter might or might
-not detect the error, and if it does not detect the error the
-interpreter can behave unpredictably thereafter.  Another way to put
-this is that although mutable objects are safe to change and constant
-variables reliably prevent attempts to change them, other constants
-are not safely mutable: if a misbehaving program tries to change such a
-constant then the constant's value might actually change, or the
-program might crash or worse.  This problem occurs
-with types that have both constant and mutable members, and that have
-mutators like @code{setcar} and @code{aset} that are valid on mutable
-objects but hazardous on constants.
-
-  When the same constant occurs multiple times in a program, the Lisp
-interpreter might save time or space by reusing existing constants or
-constant components.  For example, @code{(eq "abc" "abc")} returns
+(@pxref{Constant Variables}).  The current version of Emacs might not
+signal an error when a dangerous mutation occurs, however.  The result
+is essentially undefined: the Lisp interpreter might or might not
+detect the error, and if it does not detect the error the interpreter
+can behave unpredictably thereafter.  If a misbehaving program tries
+to change such a value then it might actually succeed, or the program
+might crash or worse.  This will hopefully be improved in future
+versions of Emacs.
+
+  When the same literal occurs multiple times in a program, the Lisp
+interpreter might save time or space by reusing existing values or
+their components.  For example, @code{(eq "abc" "abc")} returns
 @code{t} if the interpreter creates only one instance of the string
-constant @code{"abc"}, and returns @code{nil} if it creates two
-instances.  Lisp programs should be written so that they work
-regardless of whether this optimization is in use.
+@code{"abc"}, and returns @code{nil} if it creates two instances.
+Lisp programs should be written so that they work regardless of
+whether this optimization is in use.
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 1cb0d05cc7..e41ce2ebe2 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -183,11 +183,11 @@ Sequence Functions
 
 @example
 @group
-(setq bar (list 1 2))  ; @r{Create a mutable list.}
+(setq bar (list 1 2))
      @result{} (1 2)
 @end group
 @group
-(setq x (vector 'foo bar))  ; @r{Create a mutable vector.}
+(setq x (vector 'foo bar))
      @result{} [foo (1 2)]
 @end group
 @group
@@ -278,7 +278,7 @@ Sequence Functions
 
 @example
 @group
-(setq x (list 'a 'b 'c))  ; @r{Create a mutable list.}
+(setq x (list 'a 'b 'c))
      @result{} (a b c)
 @end group
 @group
@@ -320,7 +320,7 @@ Sequence Functions
   For the vector, it is even simpler because you don't need setq:
 
 @example
-(setq x (copy-sequence [1 2 3 4]))  ; @r{Create a mutable vector.}
+(setq x (copy-sequence [1 2 3 4]))
      @result{} [1 2 3 4]
 (nreverse x)
      @result{} [4 3 2 1]
@@ -330,7 +330,7 @@ Sequence Functions
 
 Note that unlike @code{reverse}, this function doesn't work with strings.
 Although you can alter string data by using @code{aset}, it is strongly
-encouraged to treat strings as immutable even when they are mutable.
+encouraged to treat strings as immutable.
 
 @end defun
 
@@ -374,7 +374,7 @@ Sequence Functions
 
 @example
 @group
-(setq nums (list 1 3 2 6 5 4 0))  ; @r{Create a mutable list.}
+(setq nums (list 1 3 2 6 5 4 0))
      @result{} (1 3 2 6 5 4 0)
 @end group
 @group
@@ -1228,7 +1228,7 @@ Array Functions
 
 @example
 @group
-(setq w (vector 'foo 'bar 'baz))  ; @r{Create a mutable vector.}
+(setq w (vector 'foo 'bar 'baz))
      @result{} [foo bar baz]
 (aset w 0 'fu)
      @result{} fu
@@ -1237,7 +1237,7 @@ Array Functions
 @end group
 
 @group
-;; @r{@code{copy-sequence} creates a mutable string.}
+;; @r{@code{copy-sequence} copies the string to be modified later.}
 (setq x (copy-sequence "asdfasfd"))
      @result{} "asdfasfd"
 (aset x 3 ?Z)
@@ -1247,10 +1247,6 @@ Array Functions
 @end group
 @end example
 
-The @var{array} should be mutable; that is, it should not be a constant,
-such as the constants created via quoting or via self-evaluating forms.
-@xref{Constants and Mutability}.
-
 If @var{array} is a string and @var{object} is not a character, a
 @code{wrong-type-argument} error results.  The function converts a
 unibyte string to multibyte if necessary to insert a character.
@@ -1262,7 +1258,6 @@ Array Functions
 
 @example
 @group
-;; @r{Create a mutable vector and then fill it with zeros.}
 (setq a (copy-sequence [a b c d e f g]))
      @result{} [a b c d e f g]
 (fillarray a 0)
@@ -1271,7 +1266,6 @@ Array Functions
      @result{} [0 0 0 0 0 0 0]
 @end group
 @group
-;; @r{Create a mutable string and then fill it with "-".}
 (setq s (copy-sequence "When in the course"))
      @result{} "When in the course"
 (fillarray s ?-)
@@ -1309,9 +1303,7 @@ Vectors
   A vector, like a string or a number, is considered a constant for
 evaluation: the result of evaluating it is the same vector.  This does
 not evaluate or even examine the elements of the vector.
-@xref{Self-Evaluating Forms}.  Vectors written with square brackets
-are constants and should not be modified via @code{aset} or other
-destructive operations.  @xref{Constants and Mutability}.
+@xref{Self-Evaluating Forms}.
 
   Here are examples illustrating these principles:
 
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index a4c9c2549c..3a6de56584 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -51,8 +51,7 @@ String Basics
 operate on them with the general array and sequence functions documented
 in @ref{Sequences Arrays Vectors}.  For example, you can access or
 change individual characters in a string using the functions @code{aref}
-and @code{aset} (@pxref{Array Functions}).  However, you should not
-try to change the contents of constant strings (@pxref{Modifying Strings}).
+and @code{aset} (@pxref{Array Functions}).
 
   There are two text representations for non-@acronym{ASCII}
 characters in Emacs strings (and in buffers): unibyte and multibyte.
@@ -383,8 +382,8 @@ Modifying Strings
 
   You can alter the contents of a mutable string via operations
 described in this section.  However, you should not try to use these
-operations to alter the contents of a constant string.
-@xref{Constants and Mutability}.
+operations to alter the contents of a string literal.
+@xref{Dangerous Mutations}.
 
   The most basic way to alter the contents of an existing string is with
 @code{aset} (@pxref{Array Functions}).  @code{(aset @var{string}