#| ========================================================
These are some additional experiments with tail recursion.
Multiple versions of the same function which adds up all the numbers
in a tree which only contains numbers.
Note the variation to the 2nd cond clause.
The last function definition is the better/purer(?) way of specifying
a tail recursive form but once you get more practiced you can mix
head & tail recursive forms -- the aim is to develop "elegant" code.
======================================================== |#
(defun sum-tree (tree &optional (sum 0))
(cond ((null tree)
sum
)
((listp (first tree))
(+ sum
(sum-tree (first tree))
(sum-tree (rest tree)))
)
(t
(sum-tree (rest tree) (+ sum (first tree)))
)))
(defun sum-tree (tree &optional (sum 0))
(cond ((null tree)
sum
)
((listp (first tree))
(+ sum
(sum-tree (rest tree) (sum-tree (first tree))))
)
(t
(sum-tree (rest tree) (+ sum (first tree)))
)))
(defun sum-tree (tree &optional (sum 0))
(cond ((null tree)
sum
)
((listp (first tree))
(+ (sum-tree (first tree) sum)
(sum-tree (rest tree)))
)
(t
(sum-tree (rest tree) (+ sum (first tree)))
)))
(defun sum-tree (tree &optional (sum 0))
(cond ((null tree)
sum
)
((listp (first tree))
(sum-tree (rest tree) (sum-tree (first tree) sum))
)
(t
(sum-tree (rest tree) (+ sum (first tree)))
)))
;;____ testing ____________________________
(defmatch run-a-test ((?n - ?call => ?result))
(unless (equal #?result (eval #?call))
(pprint (match>> '(failed test. ?n -- ?call)))))
(defun tester (tests)
(mapcar #'run-a-test tests)
'test-completed)
;; some tests (including 2 that fail)
(defparameter tests
'((test1 - (sum-tree nil) => 0)
(test2 - (sum-tree '(1 5 2 3 4)) => 15)
(test3 - (sum-tree '((((1 6))(5 (7 (2 9)) 8) 3 4))) => 45)
))