The code in question is this:
(define multirember&co
(lambda (a lat col)
(cond
((null? lat)
(col (quote ()) (quote ())))
((eq? (car lat) a)
(multirember&co a
(cdr lat)
(lambda (newlat seen)
(col newlat
(cons (car lat) seen)))))
(else
(multirember&co a
(cdr lat)
(lambda (newlat seen)
(col (cons (car lat) newlat)
seen))))))
I’ve stared at this all day but I can’t quite seem to understand it. When you recur on the function you are re-defining col but in the examples they seem to use the original definition. Why wouldn’t it change. How can you recur on it without passing in the parameters newlat and seen.
It’s hard to explain my question because I seem to just be missing a piece. If perhaps someone could give a more explicit walk-through than the book I may be able to understand how it works.
Let’s step through an example; maybe that will help. 🙂 For simplicity, I’m just going to use
listas the collector/continuation, which will just return a list with the arguments to the continuation.At the start,
At the first iteration, the
(eq? (car lat) a)condition matches, sincelatis not empty, and the first element oflatis'foo. This sets up the next recursion tomultirember&cothusly:At the next iteration, the
elsematches: sincelatis not empty, and the first element oflatis'bar(and not'foo). Thus, for the next recursion, we then have:For ease of human reading (and avoid confusion), we can rename the parameters (due to lexical scoping), without any change to the program’s semantics:
Finally, the
(null? lat)clause matches, sincelatis now empty. So we callwhich expands to:
which (when substituting
newlat1 = '()andseen1 = '()) becomesor (evaluating
(cons 'bar '()))Now, substituting the values
newlat2 = '(bar)andseen2 = '(), we getor, in other words,
to give our final result of