Tracing Clojure Functions

One of the best interactive debugging features of Lisp dialects is the ability to trace functions. A trace prints the arguments when the function is entered and the value of the function when it exits; indentation shows the level of recursive nesting.

While Clojure does not have a native tracing feature, there is a package that provides useful tracing features.

First, load the file of tracing functions:

(load-file "cs378/trace.clj")

Wrapping a function call in (trace ...) will generate a trace printout of the value of that call.

user=> (trace (* 2 3))
TRACE: 6
6 

To trace a function, redefine the function using deftrace rather than defn. To remove the trace, redefine the function with defn.

(deftrace factorial [n]
  (if (= n 0) 1 (* n (factorial (- n 1)))))

user=> (factorial 4)
TRACE t256: (factorial 4)
TRACE t257: | (factorial 3)
TRACE t258: | | (factorial 2)
TRACE t259: | | | (factorial 1)
TRACE t260: | | | | (factorial 0)
TRACE t260: | | | | => 1
TRACE t259: | | | => 1
TRACE t258: | | => 2
TRACE t257: | => 6
TRACE t256: => 24
24 
The first set of lines show the recursive calls to the factorial function with argument values; the lines with => show the result of each call at the corresponding level of indentation.