1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-24 10:38:38 +00:00

Improve mutability documentation

This change was inspired by comments from Štěpán Němec in:
https://lists.gnu.org/r/emacs-devel/2020-04/msg01063.html
* doc/lispref/objects.texi (Lisp Data Types): Mention mutability.
(Constants and mutability): New section.
* doc/lispintro/emacs-lisp-intro.texi (Lists diagrammed)
(Indent Tabs Mode): Improve wording.
* doc/lispref/eval.texi (Self-Evaluating Forms):
Say that they return constants.
* doc/lispref/lists.texi (Sets And Lists):
Fix memql mistake/confusion that I recently introduced.
This commit is contained in:
Paul Eggert 2020-04-19 12:00:49 -07:00
parent 81e7d7f111
commit dca35b31d0
7 changed files with 69 additions and 15 deletions

View File

@ -9557,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. points to the symbol @code{nil}, which marks the end of the list.
@need 1200 @need 1200
When a variable is set to a list via @code{setq}, When a variable is set to a list with an operation such as @code{setq},
it stores the address of the first box in the variable. Thus, it stores the address of the first box in the variable. Thus,
evaluation of the expression evaluation of the expression
@ -17140,7 +17140,7 @@ The following turns off Indent Tabs mode:
@end smallexample @end smallexample
Note that this line uses @code{setq-default} rather than the Note that this line uses @code{setq-default} rather than the
@code{setq} that we have seen before. The @code{setq-default} @code{setq} that we have seen before; @code{setq-default}
sets values only in buffers that do not have their own local sets values only in buffers that do not have their own local
values for the variable. values for the variable.

View File

@ -297,6 +297,7 @@ Lisp Data Types
* Circular Objects:: Read syntax for circular structure. * Circular Objects:: Read syntax for circular structure.
* Type Predicates:: Tests related to types. * Type Predicates:: Tests related to types.
* Equality Predicates:: Tests of equality between any two objects. * Equality Predicates:: Tests of equality between any two objects.
* Constants and Mutability:: Whether an object's value can change.
Programming Types Programming Types

View File

@ -158,6 +158,12 @@ contents unchanged.
@end group @end group
@end example @end example
A self-evaluating form yields a constant, and you should not attempt
to modify the constant's contents via @code{setcar}, @code{aset} or
similar primitives. 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 It is common to write numbers, characters, strings, and even vectors
in Lisp code, taking advantage of the fact that they self-evaluate. 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 However, it is quite unusual to do this for types that lack a read
@ -559,6 +565,7 @@ and vectors.)
@defspec quote object @defspec quote object
This special form returns @var{object}, without evaluating it. This special form returns @var{object}, without evaluating it.
The returned value is a constant, and should not be modified. The returned value is a constant, and should not be modified.
@xref{Constants and Mutability}.
@end defspec @end defspec
@cindex @samp{'} for quoting @cindex @samp{'} for quoting

View File

@ -866,16 +866,15 @@ foo ;; @r{@code{foo} was changed.}
@node Modifying Lists @node Modifying Lists
@section Modifying Existing List Structure @section Modifying Existing List Structure
@cindex destructive list operations @cindex destructive list operations
@cindex constant lists
@cindex mutable lists @cindex mutable lists
You can modify the @sc{car} and @sc{cdr} contents of a cons cell with the 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 primitives @code{setcar} and @code{setcdr}. These are destructive
operations because they change existing list structure. operations because they change existing list structure.
Destructive operations should be applied only to @dfn{mutable} lists, Destructive operations should be applied only to mutable lists,
that is, lists constructed via @code{cons}, @code{list} or similar that is, lists constructed via @code{cons}, @code{list} or similar
operations. Lists created by quoting are constants and should not be operations. Lists created by quoting are constants and should not be
changed by destructive operations. changed by destructive operations. @xref{Constants and Mutability}.
@cindex CL note---@code{rplaca} vs @code{setcar} @cindex CL note---@code{rplaca} vs @code{setcar}
@quotation @quotation
@ -1169,9 +1168,9 @@ x
@end group @end group
@end example @end example
However, the other arguments (all but the last) must be mutable 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 A common pitfall is to use a constant list as a non-last
argument to @code{nconc}. If you do this, the resulting behavior argument to @code{nconc}. If you do this, the resulting behavior
is undefined. It is possible that your program will change is undefined. It is possible that your program will change
each time you run it! Here is what might happen (though this each time you run it! Here is what might happen (though this
@ -1359,12 +1358,12 @@ Compare this with @code{memq}:
@example @example
@group @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) @result{} (1.2 1.3)
@end group @end group
@group @group
(memq (list 2) '((1) (2))) ; @r{@code{(list 2)} and @code{(2)} are not @code{eq}.} (memq 1.2 '(1.1 1.2 1.3)) ; @r{@code{1.2} and @code{1.2} need not be @code{eq}.}
@result{} nil @result{} nil ; @r{... or it might be @code{(1.2 1.3)}.}
@end group @end group
@end example @end example
@end defun @end defun
@ -1628,6 +1627,7 @@ keys may not be symbols:
'(("simple leaves" . oak) '(("simple leaves" . oak)
("compound leaves" . horsechestnut))) ("compound leaves" . horsechestnut)))
;; @r{The @code{copy-sequence} means the keys are not @code{eq}.}
(assq (copy-sequence "simple leaves") leaves) (assq (copy-sequence "simple leaves") leaves)
@result{} nil @result{} nil
(assoc (copy-sequence "simple leaves") leaves) (assoc (copy-sequence "simple leaves") leaves)

View File

@ -46,6 +46,10 @@ you store in it, type and all. (Actually, a small number of Emacs
Lisp variables can only take on values of a certain type. Lisp variables can only take on values of a certain type.
@xref{Variables with Restricted Values}.) @xref{Variables with Restricted Values}.)
Some Lisp objects are @dfn{constant}: their values 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 This chapter describes the purpose, printed representation, and read
syntax of each of the standard types in GNU Emacs Lisp. Details on how syntax of each of the standard types in GNU Emacs Lisp. Details on how
to use these types can be found in later chapters. to use these types can be found in later chapters.
@ -59,6 +63,7 @@ to use these types can be found in later chapters.
* Circular Objects:: Read syntax for circular structure. * Circular Objects:: Read syntax for circular structure.
* Type Predicates:: Tests related to types. * Type Predicates:: Tests related to types.
* Equality Predicates:: Tests of equality between any two objects. * Equality Predicates:: Tests of equality between any two objects.
* Constants and Mutability:: Whether an object's value can change.
@end menu @end menu
@node Printed Representation @node Printed Representation
@ -2373,3 +2378,43 @@ that for two strings to be equal, they have the same text properties.
@end group @end group
@end example @end example
@end defun @end defun
@node Constants and Mutability
@section Constants and Mutability
@cindex constants
@cindex mutable objects
Some Lisp objects are constant: their values never change.
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: their values can be changed
via destructive operations involving side effects. For example, an
existing marker can be changed by moving the marker to point to
somewhere else.
Although numbers are always constants and markers are always
mutable, some types contain both constant and mutable members. These
types include conses, vectors, and strings. 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 program should not attempt to modify a constant 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 mutable objects are safe to change, whereas constants are
not safely mutable: if you try to change a constant your program might
behave as you expect but it 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.

View File

@ -1249,7 +1249,7 @@ x
The @var{array} should be mutable; that is, it should not be a constant, 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. such as the constants created via quoting or via self-evaluating forms.
@xref{Self-Evaluating Forms}. @xref{Constants and Mutability}.
If @var{array} is a string and @var{object} is not a character, a If @var{array} is a string and @var{object} is not a character, a
@code{wrong-type-argument} error results. The function converts a @code{wrong-type-argument} error results. The function converts a
@ -1306,10 +1306,10 @@ same way in Lisp input.
A vector, like a string or a number, is considered a constant for 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 evaluation: the result of evaluating it is the same vector. This does
not evaluate or even examine the elements of the vector. Vectors not evaluate or even examine the elements of the vector.
written with square brackets are constants and should not be modified @xref{Self-Evaluating Forms}. Vectors written with square brackets
via @code{aset} or other destructive operations. are constants and should not be modified via @code{aset} or other
@xref{Self-Evaluating Forms}. destructive operations. @xref{Constants and Mutability}.
Here are examples illustrating these principles: Here are examples illustrating these principles:

View File

@ -384,6 +384,7 @@ usual value is @w{@code{"[ \f\t\n\r\v]+"}}.
You can alter the contents of a mutable string via operations You can alter the contents of a mutable string via operations
described in this section. However, you should not try to use these described in this section. However, you should not try to use these
operations to alter the contents of a constant string. 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 The most basic way to alter the contents of an existing string is with
@code{aset} (@pxref{Array Functions}). @code{(aset @var{string} @code{aset} (@pxref{Array Functions}). @code{(aset @var{string}