Mutation, though allowed, is strongly discouraged in Scheme. PLT even went so far as to remove set-car!
and set-cdr!
(though they "replaced" them with set-mcar!
and set-mcdr!
). However, a spec for append!
appeared in SRFI-1. This append!
is a little different than yours. In the SRFI, the implementation may, but is not required to modify the cons cells to append the lists.
If you want to have an append!
that is guaranteed to change the structure of the list that's being appended to, you'll probably have to write it yourself. It's not hard:
(define (my-append! a b)
(if (null? (cdr a))
(set-cdr! a b)
(my-append! (cdr a) b)))
To keep the definition simple, there is no error checking here, but it's clear that you will need to pass in a list of length at least 1 as a
, and (preferably) a list (of any length) as b
. The reason a
must be at least length 1 is because you can't set-cdr!
on an empty list.
Since you're interested in how this works, I'll see if I can explain. Basically, what we want to do is go down the list a
until we get to the last cons
pair, which is (<last element> . null)
. So we first see if a
is already the last element in the list by checking for null
in the cdr
. If it is, we use set-cdr!
to set it to the list we're appending, and we're done. If not, we have to call my-append!
on the cdr
of a
. Each time we do this we get closer to the end of a
. Since this is a mutation operation, we're not going to return anything, so we don't need to worry about forming our modified list as the return value.