reverse, nreverse
reverse, nreverse Function
Syntax:
reverse sequence → reversed-sequence
nreverse sequence → reversed-sequence
Arguments and Values:
sequence—a proper sequence.
reversed-sequence—a sequence.
Description:
reverse and nreverse return a new sequence of the same kind as sequence, containing the same elements, but in reverse order.
reverse and nreverse differ in that reverse always creates and returns a new sequence, whereas nreverse might modify and return the given sequence. reverse never modifies the given sequence.
For reverse, if sequence is a vector , the result is a fresh simple array of rank one that has the same actual array element type as sequence. If sequence is a list, the result is a fresh list.
For nreverse, if sequence is a vector , the result is a vector that has the same actual array element type as sequence. If sequence is a list, the result is a list.
For nreverse, sequence might be destroyed and re-used to produce the result. The result might or might not be identical to sequence. Specifically, when sequence is a list, nreverse is permitted to setf any part, car or cdr, of any cons that is part of the list structure of sequence. When sequence
is a vector , nreverse is permitted to re-order the elements of sequence in order to produce the resulting vector .
Examples:
(setq str "abc") → "abc"
(reverse str) → "cba"
str → "abc"
(setq str (copy-seq str)) → "abc"
(nreverse str) → "cba"
str → implementation-dependent
(setq l (list 1 2 3)) → (1 2 3)
(nreverse l) → (3 2 1)
l → implementation-dependent
Side Effects:
nreverse might either create a new sequence, modify the argument sequence, or both. (reverse does not modify sequence.)
Exceptional Situations:
Should be prepared to signal an error of type type-error if sequence is not a proper sequence.
Expanded Reference: reverse, nreverse
Basic reversal with reverse
reverse returns a new sequence with elements in the opposite order. The original sequence is not modified.
(reverse '(1 2 3 4 5))
=> (5 4 3 2 1)
(reverse "abcdef")
=> "fedcba"
(reverse #(a b c))
=> #(C B A)
reverse does not modify the original
(let ((lst '(1 2 3)))
(reverse lst)
lst)
=> (1 2 3)
nreverse is destructive
nreverse may modify and reuse the original sequence. Always use the return value, because the original variable binding may no longer point to the first element of the result.
(let ((lst (list 1 2 3 4 5)))
(nreverse lst))
=> (5 4 3 2 1)
Safely using nreverse
The idiomatic pattern is to capture the return value and not rely on the original binding.
(let ((lst (list 'a 'b 'c)))
(setq lst (nreverse lst))
lst)
=> (C B A)
Reversing strings
Both reverse and nreverse work with strings, since strings are sequences.
(reverse "Hello")
=> "olleH"
(nreverse (copy-seq "Common Lisp"))
=> "psiL nommoC"
Practical example: building a list by pushing then reversing
A common pattern is to build a list by pushing elements onto the front, then reversing it at the end.
(let ((result '()))
(dotimes (i 5)
(push i result))
(nreverse result))
=> (0 1 2 3 4)