20-CS-4003-001 | Organization of Programming Languages | Fall 2017 |
---|---|---|
Tail Recursion |
Tail Recursion Example
(define remove ;; Non-tail recursive (lambda (lst x) (if (null? lst) lst (if (eq? x (car lst)) (cdr lst) (cons (car lst) (remove (cdr lst) x)))))) (define test3 (let ((lst '(4 5 6 1 2 31 9 1 1 9 9 10 22 11 5 7))) (remove lst 9))) ;; Tail recursive (define remove_acc ;; Invariant: acc has all ele- (lambda (lst x acc) ;; ments seen prior to lst and (if (null? lst) ;; none is equal to x acc ;; Invariant implies x was not (if (eq? x (car lst)) ;; in the original list (append acc (cdr lst)) (remove_acc (cdr lst) x (append acc (list (car lst)))))))) (define test4 (let ((lst '(4 5 6 1 2 31 9 1 1 9 9 10 22 11 5 7))) (remove_acc lst 9 '()))) | - | The function remove removes the leftmost occurrence of a given token x from a lst or returns lst in case x is not a member. The function is not tail recursive. The function remove_acc is tail recursive. The invariant is: acc contains all list elements seen prior to lst, none of which contains x. The invariant holds on every call because only elements not equal to x are appended to acc and every such element is appended. When lst is empty, all elements of the given list are not equal to x. When x equals the (car lst) the invariant implies that the list returned has the first occurrence of x (which is (car lst) missing and that is the only element of the given list that is missing. |