; Tail recursion ; recursion where we carry the partial results with us ; that is, we do not operate on the front of the recursive call, but instead ; modify the arguments ; ; a practical concern is that because we have to keep track of another variable ; we need to call a kernel function which passes that variable to itself ; regular (front/head) recursive version of count-this-symbol ;(define count-this-symbol ; (lambda (sym ls) ; (if (null? ls) ; 0 ; (if (equal? (car ls) sym) ; (+ 1 (count-this-symbol sym (cdr ls))) ; (count-this-symbol sym (cdr ls)))))) ; tail recursive version of count-this-symbol (define count-this-symbol (lambda (sym ls) (count-this-symbol-kernel sym ls 0))) ; we pass the value 0 into sofar originally, because we have not yet seen any ; occurences of sym (define count-this-symbol-kernel (lambda (sym ls sofar) (if (null? ls) sofar (if (equal? (car ls) sym) (count-this-symbol-kernel sym (cdr ls) (+ 1 sofar)) (count-this-symbol-kernel sym (cdr ls) sofar))))) ; both versions of the procedure return the same answer ; example: (count-this-symbol 'a '(a b c a d a f)) ; returns 3 ; one caveat, when doing tail-recursion to build a list, you will find ; that the list comes out "backward" (at least in relation to how it would ; come out from regular recursion) ; the tail-recursive version of filter-out-skips (define filter-out-skips (lambda (ls) (filter-out-skips-kernel ls '()))) ; when in doubt, set sofar to what you would return as a base case value ; in regular recursion, like '() or 0 or 1 .... (define filter-out-skips-kernel (lambda (ls sofar) (if (null? ls) sofar ; almost always want to return sofar at the base case (if (equal? (car ls) 'skip) (filter-out-skips-kernel (cdr ls) sofar) (filter-out-skips-kernel (cdr ls) (cons (car ls) sofar)))))) ; notice that (filter-out-skips '(skip hop skip jump skip skip skip leap)) ; returns (leap jump hop) ; why? ; because the first element goes on first, so since everyone else ; is put on in front of it, it ends up last =( ; but you can use this to your advantage if you want the list to be in the ; reverse of the order that regular recursion would put it in