# How to subtract 1 from the nth element of a list of numbers?

How do I subtract 1 from the second element of the list `(3 6)`?

``````(setq x '(3 6))
(- (nth 1 x) 1)
``````

The above quote does the math but does not return a modified list.

• The function `-` is a pure arithmetic function which accepts numbers and returns a number. It knows nothing about where the arguments came from and does not modify any stored data. If you care about the result of the arithmetic operation then you should store it back in the list, e.g. using the convenient macros listed in the answer(s) below. Be careful, though, not to destructively modify quoted constant lists such as `'(3 6)` in-place; make a copy of the list using `copy-sequence` first or allocate a new one using `(list 3 6)` instead. Commented Feb 11, 2020 at 14:37
• This Q and emacs.stackexchange.com/q/55428/105 are essentially the same question. One of them should be deleted. (@Basil: would you like to consolidate the underlying question as a community question?)
– Drew
Commented Feb 11, 2020 at 16:27
• @Drew How do I do that? If you know how to, feel free to do so. Commented Feb 11, 2020 at 16:45

Using the built-in `cl-lib` package, you can write the following:

``````(eval-when-compile
(require 'cl-lib))

(cl-decf (nth 1 x))
``````

Alternatively, in vanilla Elisp:

``````(setf (nth 1 x) (1- (nth 1 x)))
``````

Be careful, though, to avoid modifying quoted constant lists such as `'(3 6)` in-place, as doing so modifies the constant globally and may cause the code to behave differently in separate runs.

Instead, make sure to operate on a new list each time, e.g. via:

``````(setq x (list 3 6))
``````
• @Basil You actually hijacked low-level answer to transform it into a high-level one. You should have written your own answer. Commented Feb 11, 2020 at 14:56
• @Tobias I did not change how low- or high-level the answer is. I merely extended and corrected the answer to distinguish between `cl-lib` (not the obsolete `cl`) and vanilla Elisp, and added a warning against destructive modifications. If you or the author are opposed to these additions, you are free to revert my suggestions. Writing a separate answer for these extensions would be redundant and off-topic. Commented Feb 11, 2020 at 15:00
• @Basil: `cl.el` is not obsolete. Some features of that library are obsolete. See CL: Obsolete Features.
– Drew
Commented Feb 11, 2020 at 16:13
• FWIW, I agree that @Basil did the right thing (a right thing). He by no means hijacked anything, IMO.
– Drew
Commented Feb 11, 2020 at 16:15
• @Drew You're right, `cl.el` is not officially obsolete, but its use is discouraged in favour of `cl-lib.el` where practical. See `(cl) Organization`. Commented Feb 11, 2020 at 16:43

Just tinkering, you can use `car` and `cdr` too. I'm sure someone will comment on whether this is good or bad.

``````(let ((v 99) (p 3) (l (list 1 2 3 4)))
(setcar (nthcdr p l) (+ (car (nthcdr p l)) v))
l)
;; => (1 2 3 103)
``````