I made a super small library, which I believe works in all flavours of Clojure (I’ve tried it in JVM/CLR). It has zero dependencies. Check it out! It’s just 79 lines.
It’s wholly inspired by proto-repls
The gist of it can be found at the bottom:
(comment ;; Example usage (defn add [x y] (save :a) (+ x y)) (add 5 10) (ld :a) x ;; 5 y ;; 10 (add 20 30) (add 7 13) (print-saves :a))
The point of this library is to showcase a way of debugging, which can be seen as the
first. What I mean by this is that if we call a function, let’s say the aforementioned
add, three times:
(add 1 1) (add 2 2) (add 3 3)
If we were to have a breakpoint in
add, we would generally get the most information the
first time we call the function. Of course we could exit the first breakpoint and go to the next incantation of
add, but if we imagine
add being called 1000 times, that process would get extremely painful in the long run.
So what do we do when
first isn’t what we want? We call
rest! In this case,
save. As I showed in the example code at the beginning,
save stores all local variables at the point it is called. These variables can then later be loaded by using
ld! What this leads to is that you don’t have to know beforehand where to call
break, but instead storing all your data and later being able to filter through it.
Currently you have to do some manual work in order to filter through the data, since
ld just fetches the last stored data at a specific key. But at least you have the possibility! I hope you’ll have some use for this.
Bonus! If you only want to store data when an error occurs, it’s super easy to do things like:
(defn add [x y] (try (+ x y) (catch Exception e (save :err) (throw e)))
You get the added bonus of the error information being stored together with the variables leading to the erronous call! Combine it with your editor’s equivalent of
eval-last-sexp and you’ll be able to run different parts of your function using the variables that
defd for you. Makes for super easy debugging!