// One important technique of optimizing recursive functions // is to make sure the last call in a function is to itself, // without any work left for it to do with saved values. // This is called a "tail call" or "tail recursion", and // modern compilers know how to optimize it, to make stack // frames unnecessary. // Using accumulator arguments is a useful trick to write tail-recursive // functions where possible, or just functions that accumulate their // results: // Tail-recursive factorial: (defun foo (n acc) (cond ((eql n 0) acc) (t (foo (- n 1) (* n acc))))) ; now, a tail call =>foo (foo 1 1) =>1 (foo 5 1) =>120 (foo 6 1) =>720 // Flattening a tree using an accumulator. This example is from Chapter 4 of the OnLisp // book, pages 48--49. Read that chapter if you haven't yet! (defun flatten (lst acc) (cond ((null lst) acc) ((atom lst) (cons lst acc)) ((consp lst) (flatten (car lst) (flatten (cdr lst) acc))))) =>flatten (flatten '(1 ((2 (3)) ((((70)))))) ()) =>(1 2 3 70) // Compare it with the folding functions in reduce-log.txt. Does it remind you of one? What's // similar & different?