= Debug With OpenMCL = == Tracing Recursive Functions == '''Problem:''' Is there a way to get trace to show recursive calls in addition to the outermost call? For example, if you trace {{{fact}}} as below, it only prints the call of {{{(FACT 10 1)}}}. We would like to be able to see the call of {{{(FACT 10 1)}}}, {{{(FACT 9 10)}}}, {{{(FACT 8 90)}}}, etc., all the way down {{{ ? (defun fact (x acc) (if (= x 0) acc (fact (- x 1) (* x acc)))) FACT ? (trace fact) NIL ? (fact 10 1) 0> Calling (FACT 10 1) <0 FACT returned 3628800 3628800 }}} '''Solution:''' When a (globally named) function {{{FOO}}} is defined with {{{DEFUN}}}, the compiler is allowed to assume that functional references to that function name refer to the function being defined (unless they're lexically shadowed); it can therefore skip the implicit {{{SYMBOL-FUNCTION}}} ("call whatever is in the function cell of {{{FOO}}}") on a self-call (a call to {{{FOO}}} from within {{{FOO}}}.) This saves an instruction or two on those calls, but (since {{{TRACE}}} works by changing what {{{SYMBOL-FUNCTION}}} returns) those inlined self-calls can't be traced. However, the compiler can't do this (can't even assume that something defined by {{{DEFUN}}} won't be redefined later) if the function name is declared {{{NOTINLINE}}} at the point of the self call: {{{ ? (defun fact (x acc) (declare (NOTINLINE FACT)) ; and the compiler can't ignore NOTINLINE (if (= x 0) acc (fact (- x 1) (* x acc)))) FACT ? (trace fact) NIL ? (fact 10 1) 0> Calling (FACT 10 1) 1> Calling (FACT 9 10) 2> Calling (FACT 8 90) 3> Calling (FACT 7 720) 4> Calling (FACT 6 5040) 5> Calling (FACT 5 30240) 6> Calling (FACT 4 151200) 7> Calling (FACT 3 604800) 8> Calling (FACT 2 1814400) 9> Calling (FACT 1 3628800) 10> Calling (FACT 0 3628800) <10 FACT returned 3628800 <9 FACT returned 3628800 <8 FACT returned 3628800 <7 FACT returned 3628800 <6 FACT returned 3628800 <5 FACT returned 3628800 <4 FACT returned 3628800 <3 FACT returned 3628800 <2 FACT returned 3628800 <1 FACT returned 3628800 <0 FACT returned 3628800 3628800 ? }}} That's the way to say to the compiler, "as a matter of policy, I'd rather have the ability to trace functions which call themselves and are defined with DEFUN and don't care about saving a few cycles per self-call". '''Alternate Solution:''' Note that the '''Clozure Common Lisp''' IDE permits the function to be traced as desired from within the IDE without needing to add the {{{NOTINLINE}}} command. So, if you work within the IDE you don't have to modify the sources at all.