From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#40671: [DOC] modify literal objects Date: Sat, 18 Apr 2020 13:10:30 -0700 Organization: UCLA Computer Science Department Message-ID: References: <87v9lzmdrw.fsf@laposte.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------A896A9B4828B158D84249FAF" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="2052"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 Cc: Kevin Vigouroux , 40671-done@debbugs.gnu.org To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Apr 18 22:11:19 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jPto6-0000QC-NN for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 18 Apr 2020 22:11:18 +0200 Original-Received: from localhost ([::1]:33038 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jPto5-0005Ah-QG for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 18 Apr 2020 16:11:17 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:47136) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jPtnr-00059F-V6 for bug-gnu-emacs@gnu.org; Sat, 18 Apr 2020 16:11:06 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.90_1) (envelope-from ) id 1jPtnq-0003PL-SU for bug-gnu-emacs@gnu.org; Sat, 18 Apr 2020 16:11:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:60316) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jPtnq-0003Oz-D7 for bug-gnu-emacs@gnu.org; Sat, 18 Apr 2020 16:11:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jPtnq-0002z3-7N for bug-gnu-emacs@gnu.org; Sat, 18 Apr 2020 16:11:02 -0400 In-Reply-To: <87v9lzmdrw.fsf@laposte.net> Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-To: bug-gnu-emacs@gnu.org Resent-Date: Sat, 18 Apr 2020 20:11:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: cc-closed 40671 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Mail-Followup-To: 40671@debbugs.gnu.org, eggert@cs.ucla.edu, ke.vigouroux@laposte.net Original-Received: via spool by 40671-done@debbugs.gnu.org id=D40671.158724064511434 (code D ref 40671); Sat, 18 Apr 2020 20:11:01 +0000 Original-Received: (at 40671-done) by debbugs.gnu.org; 18 Apr 2020 20:10:45 +0000 Original-Received: from localhost ([127.0.0.1]:43627 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPtnY-0002yL-5h for submit@debbugs.gnu.org; Sat, 18 Apr 2020 16:10:45 -0400 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:48676) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPtnW-0002y9-3M for 40671-done@debbugs.gnu.org; Sat, 18 Apr 2020 16:10:43 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 9A09F1600C7; Sat, 18 Apr 2020 13:10:36 -0700 (PDT) Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id ZsGAYoTc94Qn; Sat, 18 Apr 2020 13:10:34 -0700 (PDT) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 66CAE1600D1; Sat, 18 Apr 2020 13:10:34 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 39L9RBip98km; Sat, 18 Apr 2020 13:10:34 -0700 (PDT) Original-Received: from [192.168.1.9] (cpe-23-242-74-103.socal.res.rr.com [23.242.74.103]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 0E4901600C7; Sat, 18 Apr 2020 13:10:34 -0700 (PDT) Content-Language: en-US X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:178596 Archived-At: This is a multi-part message in MIME format. --------------A896A9B4828B158D84249FAF Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Mattias, thanks for going through the Emacs manual and looking for mistakes in this area. I know it was a pain to do that, since I did something similar in parallel and it was painful for me. I used your patch to crosscheck with my draft (finding omissions on both sides) and installed the resulting patch (attached) into the emacs-27 branch. This patch should address the points that Eli raised. That is, it adds explanations of the issue (both in the intro and the reference manual, since the issue also infects the intro), and it attempts to change examples only when the changes are needed to avoid undefined behavior in Emacs Lisp. I also kept the changes from '< to #'< that were in your patch since that's good style. --------------A896A9B4828B158D84249FAF Content-Type: text/x-patch; charset=UTF-8; name="0001-Document-constant-vs-mutable-objects-better.patch" Content-Disposition: attachment; filename="0001-Document-constant-vs-mutable-objects-better.patch" Content-Transfer-Encoding: quoted-printable >From eebfb72c906755c0a80d92c11deee7ac9faf5f4b Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 18 Apr 2020 12:59:17 -0700 Subject: [PATCH] Document constant vs mutable objects better MIME-Version: 1.0 Content-Type: text/plain; charset=3DUTF-8 Content-Transfer-Encoding: 8bit This patch builds on a suggested patch by Mattias Engdeg=C3=A5rd 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 | 32 +++++++++------ doc/lispref/edebug.texi | 2 +- doc/lispref/keymaps.texi | 8 ++-- doc/lispref/lists.texi | 60 +++++++++++++++++------------ doc/lispref/sequences.texi | 31 +++++++++------ doc/lispref/strings.texi | 17 +++++--- 6 files changed, 91 insertions(+), 59 deletions(-) diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-li= sp-intro.texi index bd688070a3..630676d978 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -2329,7 +2329,7 @@ area. =20 @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.) =20 @@ -4517,7 +4517,7 @@ number; it will be printed as the character with th= at @sc{ascii} code. =20 @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. =20 @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: =20 @smallexample -(setq animals '(antelope giraffe lion tiger)) +(setq animals (list 'antelope 'giraffe 'lion 'tiger)) @end smallexample =20 @noindent @@ -7398,7 +7408,7 @@ To see how this works, set the value of the variabl= e to a list of domesticated animals by evaluating the following expression: =20 @smallexample -(setq domesticated-animals '(horse cow sheep goat)) +(setq domesticated-animals (list 'horse 'cow 'sheep 'goat)) @end smallexample =20 @need 1200 @@ -8846,7 +8856,7 @@ and then find the value of @code{trees}: =20 @smallexample @group -(setq trees '(maple oak pine birch)) +(setq trees (list 'maple 'oak 'pine 'birch)) @result{} (maple oak pine birch) @end group =20 @@ -9366,7 +9376,7 @@ For example: =20 @smallexample @group -(setq triple '(1 2 3)) +(setq triple (list 1 2 3)) =20 (setcar triple '37) =20 @@ -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. =20 @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 =20 @@ -17092,7 +17102,7 @@ reminders. =20 @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.'' =20 @@ -17130,8 +17140,8 @@ The following turns off Indent Tabs mode: @end smallexample =20 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. =20 @ifinfo diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 8be8307c75..ec76e83db1 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -858,7 +858,7 @@ to a non-@code{nil} value. Here is an example of code that creates a circular structure: =20 @example -(setq a '(x y)) +(setq a (list 'x 'y)) (setcar a a) @end example =20 diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index c6a02d721f..4db9969767 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -1441,10 +1441,10 @@ Here is an example showing a keymap before and af= ter substitution: =20 @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 =20 diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index 27fa5385e3..c2771b0165 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -866,10 +866,16 @@ foo ;; @r{@code{foo} was chan= ged.} @node Modifying Lists @section Modifying Existing List Structure @cindex destructive list operations +@cindex constant lists +@cindex mutable lists =20 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. =20 @cindex CL note---@code{rplaca} vs @code{setcar} @quotation @@ -906,7 +912,7 @@ value @var{object}. For example: =20 @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}. =20 @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: =20 @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. =20 @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 =20 @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: =20 @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 =20 -However, the other arguments (all but the last) must be lists. +However, the other arguments (all but the last) must be mutable lists. =20 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): =20 @smallexample @group @@ -1260,7 +1268,9 @@ after those elements. For example: =20 @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 =20 @@ -1270,7 +1280,7 @@ removing it involves changing the @sc{cdr}s (@pxref= {Setcdr}). =20 @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 =20 -In the following example, the @code{(4)} that @code{delq} attempts to ma= tch -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 @c= ode{eq}: =20 @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}. =20 @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}: =20 @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 @c= ode{equal}.} @result{} ((2)) @end group @group -(memq '(2) '((1) (2))) ; @r{@code{(2)} and @code{(2)} are not @code{e= q}.} +(memq (list 2) '((1) (2))) ; @r{@code{(list 2)} and @code{(2)} are no= t @code{eq}.} @result{} nil @end group @group @@ -1407,7 +1417,7 @@ For example: =20 @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))) =20 -(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}. =20 @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, =20 @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) diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 1a3a04f680..f6faf9448c 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -183,7 +183,7 @@ for other ways to copy sequences. =20 @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. =20 @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: =20 @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 =20 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. =20 @end defun =20 @@ -374,11 +374,11 @@ appears in a different position in the list due to = the change of =20 @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: =20 @example -(setq nums (sort nums '<)) +(setq nums (sort nums #'<)) @end example =20 For the better understanding of what stable sort is, consider the follow= ing @@ -1228,7 +1228,7 @@ This function sets the @var{index}th element of @va= r{array} to be =20 @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 =20 @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 =20 +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 re= turns @var{array}. =20 @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. =20 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}. =20 Here are examples illustrating these principles: diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 14cabc5d79..3acbf538dc 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -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= }). =20 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 @re= f{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. =20 @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 =20 + 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}): =20 @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 =20 @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 --=20 2.17.1 --------------A896A9B4828B158D84249FAF--