Next: , Previous: Lists as sequences, Up: Common List Functions


7.2.1.4 Destructive list operations

These procedures may mutate the list they operate on, but any such mutation is undefined.

— Procedure: nconc args

nconc destructively concatenates its arguments. (Compare this with append, which copies arguments rather than destroying them.) Sometimes called append! (see Rev2 Procedures).

Example: You want to find the subsets of a set. Here's the obvious way:

          (define (subsets set)
            (if (null? set)
                '(())
                (append (map (lambda (sub) (cons (car set) sub))
                             (subsets (cdr set)))
                        (subsets (cdr set)))))

But that does way more consing than you need. Instead, you could replace the append with nconc, since you don't have any need for all the intermediate results.

Example:

          (define x '(a b c))
          (define y '(d e f))
          (nconc x y)
             ⇒ (a b c d e f)
          x
             ⇒ (a b c d e f)

nconc is the same as append! in sc2.scm.

— Procedure: nreverse lst

nreverse reverses the order of elements in lst by mutating cdrs of the list. Sometimes called reverse!.

Example:

          (define foo '(a b c))
          (nreverse foo)
             ⇒ (c b a)
          foo
             ⇒ (a)

Some people have been confused about how to use nreverse, thinking that it doesn't return a value. It needs to be pointed out that

          (set! lst (nreverse lst))

is the proper usage, not

          (nreverse lst)

The example should suffice to show why this is the case.

— Procedure: delete elt lst
— Procedure: delete-if pred lst
— Procedure: delete-if-not pred lst

Destructive versions of remove remove-if, and remove-if-not.

Example:

          (define lst (list 'foo 'bar 'baz 'bang))
          (delete 'foo lst)
             ⇒ (bar baz bang)
          lst
             ⇒ (foo bar baz bang)
          
          (define lst (list 1 2 3 4 5 6 7 8 9))
          (delete-if odd? lst)
             ⇒ (2 4 6 8)
          lst
             ⇒ (1 2 4 6 8)

Some people have been confused about how to use delete, delete-if, and delete-if, thinking that they don't return a value. It needs to be pointed out that

          (set! lst (delete el lst))

is the proper usage, not

          (delete el lst)

The examples should suffice to show why this is the case.