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: Wed, 29 Apr 2020 09:36:21 -0700 Organization: UCLA Computer Science Department Message-ID: References: <871rofxbz9.fsf@web.de> <93463227-33a8-85a0-fd19-8b29b75997f3@yandex.ru> <969b3497-0afd-d104-6792-d744d31548fa@cs.ucla.edu> <2935ec84-bdea-2e20-01b9-8ed08cc61c6c@yandex.ru> <669981e5-f601-5c18-1a8b-ee316ad001ec@cs.ucla.edu> <4b8b7e98-029e-58ac-59ff-6cd984b7eb85@yandex.ru> <530d3597-aaaa-f019-bafa-8229d13e7248@yandex.ru> <60b88f52-c50d-c57a-9ce5-495e6157d36e@cs.ucla.edu> <0721d8c1-4fe3-335c-7dbc-171487cb648a@yandex.ru> <6d1015da-0dc1-376c-f84b-5e3ee3149213@cs.ucla.edu> <286139d2-bbe1-2d5a-bec1-f781666376f1@yandex.ru> <10b89e6f-6fa6-f855-65b6-3361a74472d3@cs.ucla.edu> <1080866d-778f-493e-9c51-3893eeaf7203@default> <3aa1e901-c74e-e2cb-f47f-99aa939f3821@cs.ucla.edu> <87blnbp1x0.fsf@web.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------8585C31DD5A6FA609D92FEA6" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="81040"; 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: ke.vigouroux@laposte.net, 40671@debbugs.gnu.org, Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= , Dmitry Gutov , Richard Stallman To: Michael Heerdegen Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Wed Apr 29 18:41:52 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 1jTpmR-000KyF-Uc for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 29 Apr 2020 18:41:52 +0200 Original-Received: from localhost ([::1]:38086 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jTpmQ-0007oo-Ga for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 29 Apr 2020 12:41:50 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:49242) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jTpl0-0007gR-RT for bug-gnu-emacs@gnu.org; Wed, 29 Apr 2020 12:41:41 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.90_1) (envelope-from ) id 1jTphm-0004qr-F1 for bug-gnu-emacs@gnu.org; Wed, 29 Apr 2020 12:40:22 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:32876) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jTphm-0004ov-1K for bug-gnu-emacs@gnu.org; Wed, 29 Apr 2020 12:37:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jTphl-0004qO-TS for bug-gnu-emacs@gnu.org; Wed, 29 Apr 2020 12:37:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 29 Apr 2020 16:37:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 40671 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 40671-submit@debbugs.gnu.org id=B40671.158817819218570 (code B ref 40671); Wed, 29 Apr 2020 16:37:01 +0000 Original-Received: (at 40671) by debbugs.gnu.org; 29 Apr 2020 16:36:32 +0000 Original-Received: from localhost ([127.0.0.1]:44422 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTphH-0004pR-TG for submit@debbugs.gnu.org; Wed, 29 Apr 2020 12:36:32 -0400 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:40968) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTphG-0004pD-4a for 40671@debbugs.gnu.org; Wed, 29 Apr 2020 12:36:31 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 966C6160017; Wed, 29 Apr 2020 09:36:24 -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 0G9KZq38xx00; Wed, 29 Apr 2020 09:36:22 -0700 (PDT) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 4BA11160066; Wed, 29 Apr 2020 09:36:22 -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 Ofs9huFVdUNL; Wed, 29 Apr 2020 09:36:22 -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 7B158160017; Wed, 29 Apr 2020 09:36:21 -0700 (PDT) Autocrypt: addr=eggert@cs.ucla.edu; prefer-encrypt=mutual; keydata= LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgptUUlOQkV5QWNtUUJFQURB QXlIMnhvVHU3cHBHNUQzYThGTVpFb243NGRDdmM0K3ExWEEySjJ0QnkycHdhVHFmCmhweHhk R0E5Smo1MFVKM1BENGJTVUVnTjh0TFowc2FuNDdsNVhUQUZMaTI0NTZjaVNsNW04c0thSGxH ZHQ5WG0KQUF0bVhxZVpWSVlYL1VGUzk2ZkR6ZjR4aEVtbS95N0xiWUVQUWRVZHh1NDd4QTVL aFRZcDVibHRGM1dZRHoxWQpnZDdneDA3QXV3cDdpdzdlTnZub0RUQWxLQWw4S1lEWnpiRE5D UUdFYnBZM2VmWkl2UGRlSStGV1FONFcra2doCnkrUDZhdTZQcklJaFlyYWV1YTdYRGRiMkxT MWVuM1NzbUUzUWpxZlJxSS9BMnVlOEpNd3N2WGUvV0szOEV6czYKeDc0aVRhcUkzQUZINmls QWhEcXBNbmQvbXNTRVNORnQ3NkRpTzFaS1FNcjlhbVZQa25qZlBtSklTcWRoZ0IxRApsRWR3 MzRzUk9mNlY4bVp3MHhmcVQ2UEtFNDZMY0ZlZnpzMGtiZzRHT1JmOHZqRzJTZjF0azVlVThN Qml5Ti9iClowM2JLTmpOWU1wT0REUVF3dVA4NGtZTGtYMndCeHhNQWhCeHdiRFZadWR6eERa SjFDMlZYdWpDT0pWeHEya2wKakJNOUVUWXVVR3FkNzVBVzJMWHJMdzYrTXVJc0hGQVlBZ1Jy NytLY3dEZ0JBZndoU In-Reply-To: <87blnbp1x0.fsf@web.de> 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:179333 Archived-At: This is a multi-part message in MIME format. --------------8585C31DD5A6FA609D92FEA6 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit On 4/28/20 5:32 PM, Michael Heerdegen wrote: > Now stuff is already in the repo, it's inconvenient to review, I took the trouble of retrieving all changes to the emacs-27 documentation since this exercise started, discarding the irrelevant changes, with the result being the attached diff. This should make the new material more convenient to review. Of course this is not a complete substitute for reviewing what's in the manual now, as I could have well missed some stuff that needs changing. --------------8585C31DD5A6FA609D92FEA6 Content-Type: text/x-patch; charset=UTF-8; name="constants.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="constants.diff" diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index 66aa97e20a..ea16d9ef15 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -7317,11 +7317,21 @@ 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} 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 @@ setcdr 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 @@ kill-new function @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 @@ cons & search-fwd Review @smallexample @group -(setq triple '(1 2 3)) +(setq triple (list 1 2 3)) (setcar triple '37) 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 @@ Printing in Edebug 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 diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index cfd96f7aa6..bba1b63115 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -297,6 +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. Programming Types diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi index cd45c8df03..baddce4d9c 100644 --- a/doc/lispref/eval.texi +++ b/doc/lispref/eval.texi @@ -158,6 +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}. + It is common to write numbers, characters, strings, and even vectors in Lisp code, taking advantage of the fact that they self-evaluate. However, it is quite unusual to do this for types that lack a read @@ -558,6 +564,8 @@ 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 @@ -598,6 +606,12 @@ Quoting @end group @end example + 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}. + Other quoting constructs include @code{function} (@pxref{Anonymous Functions}), which causes an anonymous lambda expression written in Lisp to be compiled, and @samp{`} (@pxref{Backquote}), which is used to quote @@ -695,6 +709,9 @@ Backquote @end group @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, +vectors and strings that should not be modified. @node Eval @section Eval diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index fd269d520c..1e81fb1dc5 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -1441,10 +1441,10 @@ Changing Key Bindings @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 diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index 27fa5385e3..ea44e01f48 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -866,10 +866,15 @@ 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}. @cindex CL note---@code{rplaca} vs @code{setcar} @quotation @@ -906,7 +911,7 @@ Setcar @example @group -(setq x '(1 2)) +(setq x (list 1 2)) ; @r{Create a mutable list.} @result{} (1 2) @end group @group @@ -926,8 +931,8 @@ Setcar @example @group -;; @r{Create two lists that are partly shared.} -(setq x1 '(a b c)) +;; @r{Create two mutable lists that are partly shared.} +(setq x1 (list 'a 'b 'c)) @result{} (a b c) (setq x2 (cons 'z (cdr x1))) @result{} (z b c) @@ -1017,11 +1022,11 @@ Setcdr @example @group -(setq x '(1 2 3)) +(setq x (list 1 2 3)) ; @r{Create a mutable list.} @result{} (1 2 3) @end group @group -(setcdr x '(4)) +(setcdr x '(4)) ; @r{Modify the list's tail to be a constant list.} @result{} (4) @end group @group @@ -1037,7 +1042,7 @@ Setcdr @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 +1074,7 @@ Setcdr @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,11 +1135,11 @@ Rearrangement @example @group -(setq x '(1 2 3)) +(setq x (list 1 2 3)) ; @r{Create a mutable list.} @result{} (1 2 3) @end group @group -(nconc x '(4 5)) +(nconc x '(4 5)) ; @r{Modify the list's tail to be a constant list.} @result{} (1 2 3 4 5) @end group @group @@ -1150,7 +1155,7 @@ Rearrangement @example @group -(setq x '(1 2 3)) +(setq x (list 1 2 3)) @result{} (1 2 3) @end group @group @@ -1163,11 +1168,13 @@ Rearrangement @end group @end example -However, the other arguments (all but the last) must be lists. +However, the other arguments (all but the last) should 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: +A common pitfall is to use a constant list as a non-last +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 @@ -1270,7 +1277,7 @@ Sets And Lists @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 +1310,12 @@ Sets And Lists (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 +1331,7 @@ Sets And Lists @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 @@ -1349,12 +1356,12 @@ Sets And Lists @example @group -(memql 1.2 '(1.1 1.2 1.3)) ; @r{@code{1.2} and @code{1.2} are @code{eql}.} +(memql 1.2 '(1.1 1.2 1.3)) ; @r{@code{1.2} and @code{1.2} must be @code{eql}.} @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}.} - @result{} nil +(memq 1.2 '(1.1 1.2 1.3)) ; @r{@code{1.2} and @code{1.2} need not be @code{eq}.} + @result{} nil ; @r{... or it might be @code{(1.2 1.3)}.} @end group @end example @end defun @@ -1373,11 +1380,11 @@ Sets And Lists @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 +1414,7 @@ Sets And Lists @example @group -(setq l '((2) (1) (2))) +(setq l (list '(2) '(1) '(2))) (delete '(2) l) @result{} ((1)) l @@ -1416,7 +1423,7 @@ Sets And Lists ;; @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 @@ -1619,7 +1626,7 @@ Association Lists ("compound leaves" . horsechestnut))) (assq "simple leaves" leaves) - @result{} nil + @result{} @r{Unspecified; might be @code{nil} or non-@code{nil}.} (assoc "simple leaves" leaves) @result{} ("simple leaves" . oak) @end smallexample @@ -1759,7 +1766,7 @@ Association Lists 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 +1933,7 @@ Plist Access 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) diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 1c4e7e4d4e..1d5b2c690f 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -46,6 +46,10 @@ 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. @@ -59,6 +63,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. @end menu @node Printed Representation @@ -2373,3 +2378,52 @@ Equality Predicates @end group @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. + + 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}. + + 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. + + 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 +@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. diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index d89aa31e4c..1cb0d05cc7 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -183,11 +183,11 @@ Sequence Functions @example @group -(setq bar '(1 2)) +(setq bar (list 1 2)) ; @r{Create a mutable list.} @result{} (1 2) @end group @group -(setq x (vector 'foo bar)) +(setq x (vector 'foo bar)) ; @r{Create a mutable vector.} @result{} [foo (1 2)] @end group @group @@ -278,7 +278,7 @@ Sequence Functions @example @group -(setq x '(a b c)) +(setq x (list 'a 'b 'c)) ; @r{Create a mutable list.} @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 [1 2 3 4]) +(setq x (copy-sequence [1 2 3 4])) ; @r{Create a mutable vector.} @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. +encouraged to treat strings as immutable even when they are mutable. @end defun @@ -374,7 +374,7 @@ Sequence Functions @example @group -(setq nums '(1 3 2 6 5 4 0)) +(setq nums (list 1 3 2 6 5 4 0)) ; @r{Create a mutable list.} @result{} (1 3 2 6 5 4 0) @end group @group @@ -1228,7 +1228,7 @@ Array Functions @example @group -(setq w [foo bar baz]) +(setq w (vector 'foo 'bar 'baz)) ; @r{Create a mutable vector.} @result{} [foo bar baz] (aset w 0 'fu) @result{} fu @@ -1237,7 +1237,8 @@ Array Functions @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 @@ 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. @@ -1257,7 +1262,8 @@ Array Functions @example @group -(setq a [a b c d e f g]) +;; @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) @result{} [0 0 0 0 0 0 0] @@ -1265,7 +1271,8 @@ Array Functions @result{} [0 0 0 0 0 0 0] @end group @group -(setq s "When in the course") +;; @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 ?-) @result{} "------------------" @@ -1302,7 +1309,9 @@ 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}. +@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}. Here are examples illustrating these principles: diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 14cabc5d79..a4c9c2549c 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -51,10 +51,8 @@ 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, 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 @@ String Basics 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,11 @@ Modifying Strings @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. +@xref{Constants and Mutability}. + 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 +597,7 @@ Text Comparison @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 +614,7 @@ Text Comparison @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 --------------8585C31DD5A6FA609D92FEA6--