The Grinnell Scheme Web: The append
procedure

Is there a procedure for concatenating two lists into one long one?

Yes. The append procedure takes two lists -- or, indeed, any number of lists -- and returns a list consisting of all of the elements of the first list, in their original order, followed by all of the elements of the other list or lists, in their original order:

> (append (list 1 2 3) (list 4 5 6 7))
(1 2 3 4 5 6 7)
> (append '(3) '(1 4 1 5 9))
(3 1 4 1 5 9)
> (append '(1 2) '(3 4 5) '(6 7 8 9 10) '(11) '(12 13 14))
(1 2 3 4 5 6 7 8 9 10 11 12 13 14)
> (append '() '(100 200 300))
(100 200 300)
> (append '(-300 -200 -100) '())
(-300 -200 -100)
> (append '() '(1 2) '() '(3 4) '() '() '(5 6) '())
(1 2 3 4 5 6)
> (append '() '() '())
()
> (append '(1 2 3 4))
(1 2 3 4)
> (append '())
()
> (append)
()
There's a slight complication here that will become important only much later on. In constructing the value that it returns, the append procedure builds new copies of all of its operands except the last. The last argument, however, actually becomes part of the concatenated list:
> (define subchain (list 2 3 4))
> (define front (list 1))
> (define chain (append front subchain))
> chain
(1 2 3 4)
> (eq? (cdr chain) subchain)
#t
The fact that the call to eq? returns the true Boolean value means that it is not a copy of subchain, but the identical container subchain itself, that is the second component of chain.

Is that important?

Not at this point, but it will be when we take up the subject of mutation -- changing the contents of a container while retaining its identity.

So the arity of the append procedure is ``0 or more,'' and all of its operands must be lists.

Actually, the standard says that the last operand can be any object. Unless it is a list, however, append doesn't return a list. If all of the elements before the last are empty lists, append simply returns the last operand unchanged:

> (append '() '() 15)
15
> (append '() '(#f . #t))
(#f . #t)
Otherwise, if its last argument is not a list, append returns an improper list, formed by forcing that last argument into the second component of a pair:
> (append '(1 2 3) 4)
(1 2 3 . 4)
> (append '(#t #t #t #t) '((#f . #f) . (#f . #f)))
(#t #t #t #t (#f . #f) #f . #f)
In any case, all of the arguments except the last one must be lists:
> (append 1 '(2 3))

ERROR: append: Wrong type in arg  1
> (append '(#f . #f) '(#t . #t))

ERROR: append: Wrong type in arg  #f
I wouldn't think that there would be many occasions on which you'd want to call an append procedure except to concatenate lists.

Perhaps not, and maybe the design of Scheme would be cleaner if the standard required all the operands to be lists. But that's not what was done.


Next topic
Previous topic
Table of contents


This document is available on the World Wide Web as

http://www.math.grin.edu/~stone/scheme-web/append.html


created August 11, 1995
last revised December 26, 1995

Copyright 1995 by John David Stone (stone@math.grin.edu)