20-CS-4003-001 | Organization of Programming Languages | Fall 2018 |
---|---|---|
Tail Recursion |
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). |