[Openmcl-devel] TRACEing recursive functions

Gary Byers gb at clozure.com
Fri Mar 21 10:56:02 PST 2003

On 21 Mar 2003, Marco Baringer wrote:

> Apparently TRACE doesn't trace recursive function calls:
> ? (defun fact (n) (if (zerop n) 1 (* n (fact (- n 1)))))
> ? (trace fact)
> ? (fact 3)
>  Calling (FACT 3)
>  FACT returned 6
> 6
> ?
> am i doing something wrong or is this a bug?

The compiler's allowed to assume that a function definition won't
change within the body of a function defined with DEFUN that that
definition won't change; that assumption allows it to make  any
self-referential calls a few instructions shorter (it can avoid
doing an implicit SYMBOL-FUNCTION-like operation.)

There are a couple of ways to override this:

a) It can't make those assumptions in the presence of NOTINLINE

? (defun fact (n)
    (declare (notinline fact))  ; Calls to FACT must be full function calls
    (if (zerop n) 1 (* n (fact (1- n)))))

b) The "policy" under which code is compiled can be changed to disallow
this (or to allow it only under certain conditions).  The default policy
allows inlining self-calls (when NOTINLINE is not a factor) unless
(OPTIMIZE (DEBUG 3)) is in effect; that could be changed (for example)

? (setq *default-compiler-policy*
    (new-compiler-policy *default-compiler-policy*
      :allow-self-calls #'(lambda (env)
                           (= (ccl::debug-optimize-quantity env) 0))))

That'll affect the policy used for interactive compilation; there's
another "policy object" (the value of CCL:*DEFAULT-FILE-COMPILATION-POLICY*)
that affects code compiled by COMPILE-FILE.

Openmcl-devel mailing list
Openmcl-devel at clozure.com

More information about the Openmcl-devel mailing list