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

Lambda calculus, Type theory, Formal semantics, Program analysis

Prev     Next     All lectures        Code

Tail Recursion Example

 ```(define merge (lambda (x y) (if (null? x) y (if (null? y) x (if (< (car x) (car y)) (cons (car x) (merge (cdr x) y)) (cons (car y) (merge (cdr y) x))))))) (define test1 (let ((x '(3 6 7 12 24 56 57 78)) (y '(1 2 11 56 66 68 71))) (merge x y))) ;; invariant: acc is the merge of x and y tokens seen ;; before the current invocation of merge_acc (define merge_acc (lambda (x y acc) (if (null? x) (append acc y) (if (null? y) (append acc x) (if (< (car x) (car y)) (merge_acc (cdr x) y (append acc (list (car x)))) (merge_acc (cdr y) x (append acc (list (car y))))))))) (define test2 (let ((x '(3 6 7 12 24 56 57 78)) (y '(1 2 11 56 66 68 71))) (merge_acc x y '()))) ``` - The function merge takes two non-decreasing lists of numbers as input and outputs all numbers in those lists in non-decreasing order. The function is not tail recursive. The function merge_acc is tail recursive. The invariant is: acc is the merge of x and y numbers seen before the current invocation of merge_acc. The invariant holds on every call because only elements of x and y are appended to acc and each element that is appended is not less than any in acc (guaranteed by the assumption that x and y are in non-decreasing order).