]> git.eshelyaron.com Git - emacs.git/commitdiff
Document constant vs mutable objects better
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 18 Apr 2020 19:59:17 +0000 (12:59 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 18 Apr 2020 20:01:08 +0000 (13:01 -0700)
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.

doc/lispintro/emacs-lisp-intro.texi
doc/lispref/edebug.texi
doc/lispref/keymaps.texi
doc/lispref/lists.texi
doc/lispref/sequences.texi
doc/lispref/strings.texi

index bd688070a3a3b6b1cbe614f3f439d260816cdc46..630676d978621c4bca8b9af27a4488a648763c53 100644 (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
index 8be8307c75fed94d8fe6f46081873d184bf65c86..ec76e83db1cba966a5adc9bce6910d0c2fb8a53e 100644 (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
 
index c6a02d721f0aa8fb0439797c567f09118ff857ef..4db9969767c5bd9559010eb484d4ef57b7a48b1d 100644 (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
 
index 27fa5385e3526bc8869d47f6c259eca572e7c0bc..c2771b01652bd09a97975d352d9ced333902c193 100644 (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
 @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)
index 1a3a04f680b41e68b0fbe44a77df90c704df77c4..f6faf9448c2128425a4967c7b34249490c5587c2 100644 (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:
index 14cabc5d79d56731fd0d38403453a8ec46bc34b5..3acbf538dce2ad98e99127a286d72bb97280de6c 100644 (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