Otherwise great article, I hadn't heard about scope-capture.
https://docs.cider.mx/cider/debugging/debugger.html#using-th...
#dbg(defn get-first [input] (nth input 0))
(get-first [4 2 3]) ;; 4
(get-first 5) ;; gives me a stack trace and no program state
So it's nice to have, but I think this is maybe only useful if you're working through someone else's code?In conjunction with scope-capture, it is trivial to run that failing code again to have a closer look, and modify it to your liking till it runs as expected.
There are also conditional restart systems for Clojure that offer much more than this.
https://www.reddit.com/r/Clojure/comments/oe40af/debugging_i...
What would be nice is a GDB-like state along with stacktraces when you get a crash. Clojure stack traces are notoriously long and spooky. You learn to read the tea leaves, but even if you manage to identify where the crash happened and what triggered it (not always obvious..) you then need to pepper things with `println` to figure out the last local state before the whole thing blew up.
It looks like once you've found the problem area you can use `sc.api/spy` ..? It'd at least solve half the problem
println (or other logging/tracing, eg using tap) works for seeing where things go wrong, but stepping through code with a debugger works too if you're so inclined, or experimeting at the repl.
Sure, it's not always obvious what caused bad input that evnetually leads to an uncaught exception, just like in other languages.. it might have come through an event loop or other layer of indirection that doesn't show the real caller, for example.
Next time I'm in a bind I'll have to try `scope-capture`. It looks like it might get me half way there
However, as I mentioned in the article, I've found it's usually better to use scope-capture than a debugger that pauses execution. The main reason is that I mainly work with Kafka Streams atm, and when the debugger pauses one thread other threads start timing out and throwing exceptions.
It's a normal step debugger, and you can run new expressions in context are we talking about lisp restarts?
https://github.com/clojure-emacs/cider/discussions/2999
If anything Clojure needs this more than ELisp b/c of the crazy error stacks and b/c of how the laziness makes things blow up in all sorts of weird places