### A Recursive `remove` Function

#### Recap: The `remove-first` Function

In Session 9, we wrote a function named `remove-first` that takes two arguments, a symbol `s` and a list of symbols `los`. It returns a list just like `los` minus only the first occurrence of `s`.

```(define remove-first
(lambda (s los)
(if (null? los)
'()
(if (eq? (first los) s)
(rest los)
(cons (first los)
(remove-first s (rest los)))))))
```

It works:

```> (remove-first 'a '(a b c))
'(b c)
> (remove-first 'b '(a b c))
'(a c)
> (remove-first 'd '(a b c))
'(a b c)
> (remove-first 'a '())
'()
> (remove-first 'a '(a a a a a a a a a a))     ; count 'em up!
'(a a a a a a a a a)
```

For a little practice, let's try a variation of this problem.

#### The `remove` Function

What if we wanted to remove all occurrences of a symbol from a list of symbols?

The function `remove` behaves like `remove-first`, but it removes all occurrences of the symbol, not just the first. The structure of `remove-first` and `remove` are so similar that we can focus on how to modify `remove-first` to convert it into `remove`.

In terms of our code, how does the new function differ from `remove-first`?

• In the base case, our answer is still the empty list.
• If the first item in the list does not match the item to remove, then we still need to `cons` it onto the solution to the recursive step.
• If the first item in the list does match the item to remove, then we need to do something different!

So:

```(define remove
(lambda (s los)
(if (null? los)                         ; on an empty list, the
'()                                 ; answer is still empty
(if (eq? (first los) s)

;; WHAT DO WE DO HERE?

(cons (first los)               ; we still have to preserve
(remove s (rest los)))    ; non-s symbols in los
))))
```

In `remove-first`, as soon as we find `s` we return the rest of the `los`, into which are `cons`ed any non-`s` symbols that preceded `s` in `los`. But in `remove`, we need to be sure to remove not just the first `s` (by returning the `rest` of `los`) but all the `s`'s, including any that may be lurking in `(rest los)`. So:

```(define remove
(lambda (s los)
(if (null? los)
'()
(if (eq? (first los) s)
(remove s (rest los))           ;; *** HERE IS THE CHANGE! ***
(cons (first los)
(remove s (rest los)))))))
```

Does it work?

```> (remove 'a '(a b c))
(b c)
> (remove 'a '(a a a a a a a a a a))
()
```

Notice the relationship between the structure of the data and the the structure of our code. The structure of the data did not change from `remove-first` to `remove`, so neither did the structure of the function.

A small change in spec resulted in a small change in code.

`remove-first` and `remove` demonstrate the basic technique for writing recursive programs based on inductive data specifications. This is a pattern you will find in many programs, both functional and object-oriented.

We call this pattern structural recursion.