20-CS-4003-001 Organization of Programming Languages Fall 2017
Tail Recursion

Lambda calculus, Type theory, Formal semantics, Program analysis

    Prev     Next     All lectures        Code

Tail Recursion Example

(define remove  ;; Non-tail recursive
  (lambda (lst x)
    (if (null? 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))
              (cdr lst) 
              (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.