@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.)
@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
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
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
@smallexample
@group
-(setq trees '(maple oak pine birch))
+(setq trees (list 'maple 'oak 'pine 'birch))
@result{} (maple oak pine birch)
@end group
@smallexample
@group
-(setq triple '(1 2 3))
+(setq triple (list 1 2 3))
(setcar triple '37)
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
@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.''
@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
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
@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
@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
@example
@group
-(setq x '(1 2))
+(setq x (list 1 2))
@result{} (1 2)
@end group
@group
@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)
@example
@group
-(setq x '(1 2 3))
+(setq x (list 1 2 3))
@result{} (1 2 3)
@end group
@group
@example
@group
-(setq x1 '(a b c))
+(setq x1 (list 'a 'b 'c))
@result{} (a b c)
(setcdr x1 (cdr (cdr x1)))
@result{} (c)
@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)
@example
@group
-(setq x '(1 2 3))
+(setq x (list 1 2 3))
@result{} (1 2 3)
@end group
@group
@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
@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
@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
(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
@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
@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
@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
@example
@group
-(setq l '((2) (1) (2)))
+(setq l (list '(2) '(1) '(2)))
(delete '(2) l)
@result{} ((1))
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
'(("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
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))
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)
@example
@group
-(setq bar '(1 2))
+(setq bar (list 1 2))
@result{} (1 2)
@end group
@group
@example
@group
-(setq x '(a b c))
+(setq x (list 'a 'b 'c))
@result{} (a b c)
@end group
@group
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]
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
@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
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
@example
@group
-(setq w [foo bar baz])
+(setq w (vector 'foo 'bar 'baz))
@result{} [foo bar baz]
(aset w 0 'fu)
@result{} fu
@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
@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.
@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]
@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{} "------------------"
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:
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.
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
@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
@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
@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