When one is programming in an imperative programming languages such as Java one can conveniently add trace statements. For example:
for (int i=0; i<10; i++) {
// do something
// do something
System.out.println("Some trace statement");
// do something
}
How does one accomplish this in a LISP dialect such as Clojure - for example say I wanted to add a trace just before recur:
(def fact
(fn [n]
(loop [cnt n acc 1]
(if (zero? cnt)
acc
;; say I want to add a trace here
(recur (dec cnt) (* acc cnt))))))
Notes:
Lisp environments generally provide interactive debugging environment and trace mechanisms. For example, in SBCL, you could use the trace macro: you don't even need to modify your code, like you did in your Java example.
For Clojure, look at the tools.trace library, or the following answer: clojure: adding a debug trace to every function in a namespace?
See also the many answers to this question: Debugging in Clojure? Most of them involve nesting the expression you want to debug/trace inside another expression, like Chiron suggested.
I don't think that "I have to reformat and close the brackets appropriately" is a good argument; everytime you edit your program you have to deal with the syntax, or else you won't ever modify your code.
I personally don't use I am now a happy user of Paredit. Your editor keep track of parens and brackets while you code, which is quite handy.
I you really don't want to nest your expression inside another one, I suppose you could write a reader macro so that you could annotate an expression with a debug statement, but this is overkill, imho (edit: this is what spyscope does, apparently; see NielsK's answer).
The Spyscope library provides a simple option for putting in trace prints without having to change the original syntax, just in the way you (and many others) prefer.
spyscope.repl=> (take 20 (repeat #spy/p (+ 1 2 3)))
6
(6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6)
There's also ways of including trace messages
spyscope.repl=> #spy/d ^{:marker "triple-add"} (+ 1 2 3)
spyscope.repl$eval3935.invoke(NO_SOURCE_FILE:1) triple-add (+ 1 2 3) => 6
6
and even (partial) stack traces
spyscope.repl=> (take 20 (repeat #spy/d ^{:fs 3} (+ 1 2 3)))
----------------------------------------
clojure.lang.Compiler.eval(Compiler.java:6477)
clojure.lang.Compiler.eval(Compiler.java:6511)
spyscope.repl$eval675.invoke(REPL:13) (+ 1 2 3) => 6
(6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With