# Adding an element to a list in Scheme

•
•  |
•

### Question

I'm using R5RS Scheme and I just want to implement a function that returns the intersection of two given lists, but I can't do that because I cannot add an element to a list. Here is my code. How can I fix it? I'm really a beginner in Scheme - this is my first work using Scheme.

``````(define list3 '())
(define (E7 list1 list2)

(cond
((null? list1)
list3)
((member (car list1) list2) (append list3 (list (car list1))))

)
(cond
((null? list1)
list3)
((not(null? list1)) (E7 (cdr list1) list2)

)

)

)
(E7 '(4 5) '(3 4))
``````

### Solution

Here is a recursive version that does the intersection instead of the union.

``````(define (intersect list1 list2)
(cond ((null? list1)   list1)
((member (car list1) list2)   (cons (car list1) (intersect (cdr list1) list2)))
(t   (intersect (cdr list1) list2))))
``````

### OTHER TIPS

I think I see your problem. There are two ways to add an element to a list.

The first way would be actually adding it:

``````(define (intersect list1 list2)
(define newlist list2)
(do ((iter1 list1 (cdr iter1)))
(not (null? iter1))
(if (not (member (car iter1) newlist))
(set! newlist (cons (car iter1) newlist)))))
``````

(You'll probably have to look up the definition of `do` if you really want to use this.)

You may notice that that's quite ugly. That's because no one actually does it this way. Instead, you have to realize that calling a function creates a new variable as well. Try this:

``````(define (intersect list1 list2)
(cond ((null? list1) list2)
((member (car list1) list2) (intersect (cdr list1) list2))
(else (intersect (cdr list1) (cons (car list1) list2)))))
``````

If you're familiar with algorithms, you'll notice that the code I just wrote is quite slow, but it illustrates the point: in each case, you do a little bit of work and then call your function again. If you're having trouble seeing why this works, run this function instead on your example:

``````(define (intersect list1 list2)
(display list1) (display " ") (display list2) (newline)
(cond ((null? list1) list2)
((member (car list1) list2) (intersect (cdr list1) list2))
(else (intersect (cdr list1) (cons (car list1) list2)))))
``````

Here is some simplistic elisp:

``````(defun is (l1 l2)
(let ((rtn))
(mapc
(lambda (e)
(if (member e l1)
(push e rtn)))
l2)
rtn))
``````

This behaves the same as the built-in intersection for these simple tests:

``````(is '(1 2 5) '(1 4 10 5))  => (5 1)
(intersection '(1 2 5) '(1 4 10 5)) => (5 1)

(is '(1 4 10 5) '(1 2 5)) => (5 1)
(intersection '(1 4 10 5) '(1 2 5)) => (5 1)
``````

You're better off using set operations from srfi-1.