Document constant vs mutable objects better

This patch builds on a suggested patch by Mattias Engdegård
and on further comments by Eli Zaretskii.
Original bug report by Kevin Vigouroux (Bug#40671).
* doc/lispintro/emacs-lisp-intro.texi (set & setq, Review)
(setcar, Lists diagrammed, Mail Aliases, Indent Tabs Mode):
setq is a special form, not a function or command.
* doc/lispintro/emacs-lisp-intro.texi (setcar):
* doc/lispref/lists.texi (Modifying Lists, Rearrangement):
* doc/lispref/sequences.texi (Sequence Functions)
(Array Functions, Vectors):
* doc/lispref/strings.texi (String Basics, Modifying Strings):
Mention mutable vs constant objects.
* doc/lispintro/emacs-lisp-intro.texi (setcar, setcdr)
(kill-new function, cons & search-fwd Review):
* doc/lispref/edebug.texi (Printing in Edebug):
* doc/lispref/keymaps.texi (Changing Key Bindings):
* doc/lispref/lists.texi (Setcar, Setcdr, Rearrangement)
(Sets And Lists, Association Lists, Plist Access):
* doc/lispref/sequences.texi (Sequence Functions)
(Array Functions):
* doc/lispref/strings.texi (Text Comparison):
Fix examples so that they do not try to change constants.
This commit is contained in:
Paul Eggert 2020-04-18 12:59:17 -07:00
parent 6c187ed6b0
commit eebfb72c90
6 changed files with 91 additions and 59 deletions

View file

@ -2329,7 +2329,7 @@ area.
@cindex @samp{bind} defined
There are several ways by which a variable can be given a value. One of
the ways is to use either the function @code{set} or the function
the ways is to use either the function @code{set} or the special form
@code{setq}. Another way is to use @code{let} (@pxref{let}). (The
jargon for this process is to @dfn{bind} a variable to a value.)
@ -4517,7 +4517,7 @@ number; it will be printed as the character with that @sc{ascii} code.
@item setq
@itemx set
The @code{setq} function sets the value of its first argument to the
The @code{setq} special form sets the value of its first argument to the
value of the second argument. The first argument is automatically
quoted by @code{setq}. It does the same for succeeding pairs of
arguments. Another function, @code{set}, takes only two arguments and
@ -7317,11 +7317,21 @@ which leave the original list as it was. One way to find out how this
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} function. Here is a list of animals:
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
quoted form @code{'(antelope giraffe lion tiger)}, as that would yield
a list that is part of the program and bad things could happen if we
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:
@smallexample
(setq animals '(antelope giraffe lion tiger))
(setq animals (list 'antelope 'giraffe 'lion 'tiger))
@end smallexample
@noindent
@ -7398,7 +7408,7 @@ To see how this works, set the value of the variable to a list of
domesticated animals by evaluating the following expression:
@smallexample
(setq domesticated-animals '(horse cow sheep goat))
(setq domesticated-animals (list 'horse 'cow 'sheep 'goat))
@end smallexample
@need 1200
@ -8846,7 +8856,7 @@ and then find the value of @code{trees}:
@smallexample
@group
(setq trees '(maple oak pine birch))
(setq trees (list 'maple 'oak 'pine 'birch))
@result{} (maple oak pine birch)
@end group
@ -9366,7 +9376,7 @@ For example:
@smallexample
@group
(setq triple '(1 2 3))
(setq triple (list 1 2 3))
(setcar triple '37)
@ -9547,7 +9557,7 @@ part of which is the address of the next pair. The very last box
points to the symbol @code{nil}, which marks the end of the list.
@need 1200
When a variable is set to a list with a function such as @code{setq},
When a variable is set to a list via @code{setq},
it stores the address of the first box in the variable. Thus,
evaluation of the expression
@ -17092,7 +17102,7 @@ reminders.
@cindex Mail aliases
@noindent
This @code{setq} command sets the value of the variable
This @code{setq} sets the value of the variable
@code{mail-aliases} to @code{t}. Since @code{t} means true, the line
says, in effect, ``Yes, use mail aliases.''
@ -17130,8 +17140,8 @@ The following turns off Indent Tabs mode:
@end smallexample
Note that this line uses @code{setq-default} rather than the
@code{setq} command that we have seen before. The @code{setq-default}
command sets values only in buffers that do not have their own local
@code{setq} that we have seen before. The @code{setq-default}
sets values only in buffers that do not have their own local
values for the variable.
@ifinfo

View file

@ -858,7 +858,7 @@ to a non-@code{nil} value.
Here is an example of code that creates a circular structure:
@example
(setq a '(x y))
(setq a (list 'x 'y))
(setcar a a)
@end example

View file

@ -1441,10 +1441,10 @@ Here is an example showing a keymap before and after substitution:
@smallexample
@group
(setq map '(keymap
(?1 . olddef-1)
(?2 . olddef-2)
(?3 . olddef-1)))
(setq map (list 'keymap
(cons ?1 olddef-1)
(cons ?2 olddef-2)
(cons ?3 olddef-1)))
@result{} (keymap (49 . olddef-1) (50 . olddef-2) (51 . olddef-1))
@end group

View file

@ -866,10 +866,16 @@ foo ;; @r{@code{foo} was changed.}
@node Modifying Lists
@section Modifying Existing List Structure
@cindex destructive list operations
@cindex constant lists
@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 @dfn{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.
@cindex CL note---@code{rplaca} vs @code{setcar}
@quotation
@ -906,7 +912,7 @@ value @var{object}. For example:
@example
@group
(setq x '(1 2))
(setq x (list 1 2))
@result{} (1 2)
@end group
@group
@ -927,7 +933,7 @@ these lists. Here is an example:
@example
@group
;; @r{Create two lists that are partly shared.}
(setq x1 '(a b c))
(setq x1 (list 'a 'b 'c))
@result{} (a b c)
(setq x2 (cons 'z (cdr x1)))
@result{} (z b c)
@ -1017,7 +1023,7 @@ reached via the @sc{cdr}.
@example
@group
(setq x '(1 2 3))
(setq x (list 1 2 3))
@result{} (1 2 3)
@end group
@group
@ -1037,7 +1043,7 @@ the @sc{cdr} of the first cons cell:
@example
@group
(setq x1 '(a b c))
(setq x1 (list 'a 'b 'c))
@result{} (a b c)
(setcdr x1 (cdr (cdr x1)))
@result{} (c)
@ -1069,7 +1075,7 @@ of this list.
@example
@group
(setq x1 '(a b c))
(setq x1 (list 'a 'b 'c))
@result{} (a b c)
(setcdr x1 (cons 'd (cdr x1)))
@result{} (d b c)
@ -1130,7 +1136,7 @@ Unlike @code{append} (@pxref{Building Lists}), the @var{lists} are
@example
@group
(setq x '(1 2 3))
(setq x (list 1 2 3))
@result{} (1 2 3)
@end group
@group
@ -1150,7 +1156,7 @@ list:
@example
@group
(setq x '(1 2 3))
(setq x (list 1 2 3))
@result{} (1 2 3)
@end group
@group
@ -1163,11 +1169,13 @@ x
@end group
@end example
However, the other arguments (all but the last) must be lists.
However, the other arguments (all but the last) must be mutable lists.
A common pitfall is to use a quoted constant list as a non-last
argument to @code{nconc}. If you do this, your program will change
each time you run it! Here is what happens:
argument to @code{nconc}. If you do this, the resulting behavior
is undefined. It is possible that your program will change
each time you run it! Here is what might happen (though this
is not guaranteed to happen):
@smallexample
@group
@ -1260,7 +1268,9 @@ after those elements. For example:
@example
@group
(delq 'a '(a b c)) @equiv{} (cdr '(a b c))
(equal
(delq 'a (list 'a 'b 'c))
(cdr (list 'a 'b 'c)))
@end group
@end example
@ -1270,7 +1280,7 @@ removing it involves changing the @sc{cdr}s (@pxref{Setcdr}).
@example
@group
(setq sample-list '(a b c (4)))
(setq sample-list (list 'a 'b 'c '(4)))
@result{} (a b c (4))
@end group
@group
@ -1303,12 +1313,12 @@ into the variable that held the original list:
(setq flowers (delq 'rose flowers))
@end example
In the following example, the @code{(4)} that @code{delq} attempts to match
and the @code{(4)} in the @code{sample-list} are not @code{eq}:
In the following example, the @code{(list 4)} that @code{delq} attempts to match
and the @code{(4)} in the @code{sample-list} are @code{equal} but not @code{eq}:
@example
@group
(delq '(4) sample-list)
(delq (list 4) sample-list)
@result{} (a c (4))
@end group
@end example
@ -1324,7 +1334,7 @@ of @code{list}.
@example
@group
(setq sample-list '(a b c a b c))
(setq sample-list (list 'a 'b 'c 'a 'b 'c))
@result{} (a b c a b c)
@end group
@group
@ -1353,7 +1363,7 @@ Compare this with @code{memq}:
@result{} (1.2 1.3)
@end group
@group
(memq 1.2 '(1.1 1.2 1.3)) ; @r{@code{1.2} and @code{1.2} are not @code{eq}.}
(memq (list 2) '((1) (2))) ; @r{@code{(list 2)} and @code{(2)} are not @code{eq}.}
@result{} nil
@end group
@end example
@ -1373,11 +1383,11 @@ Compare this with @code{memq}:
@example
@group
(member '(2) '((1) (2))) ; @r{@code{(2)} and @code{(2)} are @code{equal}.}
(member (list 2) '((1) (2))) ; @r{@code{(list 2)} and @code{(2)} are @code{equal}.}
@result{} ((2))
@end group
@group
(memq '(2) '((1) (2))) ; @r{@code{(2)} and @code{(2)} are not @code{eq}.}
(memq (list 2) '((1) (2))) ; @r{@code{(list 2)} and @code{(2)} are not @code{eq}.}
@result{} nil
@end group
@group
@ -1407,7 +1417,7 @@ For example:
@example
@group
(setq l '((2) (1) (2)))
(setq l (list '(2) '(1) '(2)))
(delete '(2) l)
@result{} ((1))
l
@ -1416,7 +1426,7 @@ l
;; @r{write @code{(setq l (delete '(2) l))}.}
@end group
@group
(setq l '((2) (1) (2)))
(setq l (list '(2) '(1) '(2)))
(delete '(1) l)
@result{} ((2) (2))
l
@ -1618,9 +1628,9 @@ keys may not be symbols:
'(("simple leaves" . oak)
("compound leaves" . horsechestnut)))
(assq "simple leaves" leaves)
(assq (copy-sequence "simple leaves") leaves)
@result{} nil
(assoc "simple leaves" leaves)
(assoc (copy-sequence "simple leaves") leaves)
@result{} ("simple leaves" . oak)
@end smallexample
@end defun
@ -1759,7 +1769,7 @@ correct results, use the return value of @code{assq-delete-all} rather
than looking at the saved value of @var{alist}.
@example
(setq alist '((foo 1) (bar 2) (foo 3) (lose 4)))
(setq alist (list '(foo 1) '(bar 2) '(foo 3) '(lose 4)))
@result{} ((foo 1) (bar 2) (foo 3) (lose 4))
(assq-delete-all 'foo alist)
@result{} ((bar 2) (lose 4))
@ -1926,7 +1936,7 @@ function returns the modified property list, so you can store that back
in the place where you got @var{plist}. For example,
@example
(setq my-plist '(bar t foo 4))
(setq my-plist (list 'bar t 'foo 4))
@result{} (bar t foo 4)
(setq my-plist (plist-put my-plist 'foo 69))
@result{} (bar t foo 69)

View file

@ -183,7 +183,7 @@ for other ways to copy sequences.
@example
@group
(setq bar '(1 2))
(setq bar (list 1 2))
@result{} (1 2)
@end group
@group
@ -278,7 +278,7 @@ Unlike @code{reverse} the original @var{sequence} may be modified.
@example
@group
(setq x '(a b c))
(setq x (list 'a 'b 'c))
@result{} (a b c)
@end group
@group
@ -320,7 +320,7 @@ presented graphically:
For the vector, it is even simpler because you don't need setq:
@example
(setq x [1 2 3 4])
(setq x (copy-sequence [1 2 3 4]))
@result{} [1 2 3 4]
(nreverse x)
@result{} [4 3 2 1]
@ -330,7 +330,7 @@ x
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.
encouraged to treat strings as immutable even when they are mutable.
@end defun
@ -374,11 +374,11 @@ appears in a different position in the list due to the change of
@example
@group
(setq nums '(1 3 2 6 5 4 0))
(setq nums (list 1 3 2 6 5 4 0))
@result{} (1 3 2 6 5 4 0)
@end group
@group
(sort nums '<)
(sort nums #'<)
@result{} (0 1 2 3 4 5 6)
@end group
@group
@ -396,7 +396,7 @@ of @code{sort} and use that. Most often we store the result back into
the variable that held the original list:
@example
(setq nums (sort nums '<))
(setq nums (sort nums #'<))
@end example
For the better understanding of what stable sort is, consider the following
@ -1228,7 +1228,7 @@ This function sets the @var{index}th element of @var{array} to be
@example
@group
(setq w [foo bar baz])
(setq w (vector 'foo 'bar 'baz))
@result{} [foo bar baz]
(aset w 0 'fu)
@result{} fu
@ -1237,7 +1237,8 @@ w
@end group
@group
(setq x "asdfasfd")
;; @r{@code{copy-sequence} creates a mutable string.}
(setq x (copy-sequence "asdfasfd"))
@result{} "asdfasfd"
(aset x 3 ?Z)
@result{} 90
@ -1246,6 +1247,10 @@ x
@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{Self-Evaluating Forms}.
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.
@ -1257,7 +1262,7 @@ each element of @var{array} is @var{object}. It returns @var{array}.
@example
@group
(setq a [a b c d e f g])
(setq a (copy-sequence [a b c d e f g]))
@result{} [a b c d e f g]
(fillarray a 0)
@result{} [0 0 0 0 0 0 0]
@ -1265,7 +1270,7 @@ a
@result{} [0 0 0 0 0 0 0]
@end group
@group
(setq s "When in the course")
(setq s (copy-sequence "When in the course"))
@result{} "When in the course"
(fillarray s ?-)
@result{} "------------------"
@ -1301,7 +1306,9 @@ same way in Lisp input.
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.
not evaluate or even examine the elements of the vector. Vectors
written with square brackets are constants and should not be modified
via @code{aset} or other destructive operations.
@xref{Self-Evaluating Forms}.
Here are examples illustrating these principles:

View file

@ -51,10 +51,8 @@ by a distinguished character code.
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, note that
@code{length} should @emph{not} be used for computing the width of a
string on display; use @code{string-width} (@pxref{Size of Displayed
Text}) instead.
and @code{aset} (@pxref{Array Functions}). However, you should not
try to change the contents of constant strings (@pxref{Modifying Strings}).
There are two text representations for non-@acronym{ASCII}
characters in Emacs strings (and in buffers): unibyte and multibyte.
@ -89,6 +87,9 @@ copy them into buffers. @xref{Character Type}, and @ref{String Type},
for information about the syntax of characters and strings.
@xref{Non-ASCII Characters}, for functions to convert between text
representations and to encode and decode character codes.
Also, note that @code{length} should @emph{not} be used for computing
the width of a string on display; use @code{string-width} (@pxref{Size
of Displayed Text}) instead.
@node Predicates for Strings
@section Predicates for Strings
@ -380,6 +381,10 @@ usual value is @w{@code{"[ \f\t\n\r\v]+"}}.
@cindex modifying strings
@cindex string modification
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.
The most basic way to alter the contents of an existing string is with
@code{aset} (@pxref{Array Functions}). @code{(aset @var{string}
@var{idx} @var{char})} stores @var{char} into @var{string} at index
@ -591,7 +596,7 @@ for sorting (@pxref{Sequence Functions}):
@example
@group
(sort '("11" "12" "1 1" "1 2" "1.1" "1.2") 'string-collate-lessp)
(sort (list "11" "12" "1 1" "1 2" "1.1" "1.2") 'string-collate-lessp)
@result{} ("11" "1 1" "1.1" "12" "1 2" "1.2")
@end group
@end example
@ -608,7 +613,7 @@ systems. The @var{locale} value of @code{"POSIX"} or @code{"C"} lets
@example
@group
(sort '("11" "12" "1 1" "1 2" "1.1" "1.2")
(sort (list "11" "12" "1 1" "1 2" "1.1" "1.2")
(lambda (s1 s2) (string-collate-lessp s1 s2 "POSIX")))
@result{} ("1 1" "1 2" "1.1" "1.2" "11" "12")
@end group