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:
parent
81e7d7f111
commit
dca35b31d0
@ -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.
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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.
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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}
|
||||||
|
Loading…
Reference in New Issue
Block a user