Why learning Clojure, I sometimes need to see what a function does at each step. For example:
(defn kadane [coll]
(let [pos+ (fn [sum x] (if (neg? sum) x (+ sum x)))
ending-heres (reductions pos+ 0 coll)]
(reduce max ending-heres)))
Should I insert println
here and there (where, how); or is there a suggested workflow/tool?
This may not be what you're after at the level of a single function (see Charles Duffy's comment below), but if you wanted to do get an overview of what's going on at the level of a namespace (or several), you could use tools.trace (disclosure: I'm a contributor):
(ns foo.core)
(defn foo [x] x)
(defn bar [x] (foo x))
(in-ns 'user) ; standard REPL namespace
(require '[clojure.tools.trace :as trace])
(trace/trace-ns 'foo.core)
(foo.core/bar 123)
TRACE t20387: (foo.core/bar 123)
TRACE t20388: | (foo.core/foo 123)
TRACE t20388: | => 123
TRACE t20387: => 123
It won't catch inner functions and such (as pointed out by Charles), and might be overwhelming with large code graphs, but when exploring small-ish code graphs it can be quite convenient.
(It's also possible to trace individually selected Vars if the groups of interest aren't perfectly aligned with namespaces.)
If you use Emacs with CIDER as most Clojurians do, you already have a built-in debugger:
https://docs.cider.mx/cider/debugging/debugger.html
Chances are your favorite IDE/Editor has something built-in or a plugin already.
There is also (in no particular order):
println
I would look at the above first. However there were/are other possibilities:
Also, if the function is simple enough you can add def
s at development-time to peek inside the bindings at a given time inside your function.
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