7
votes

How does one debug clojure? Is there an similar tool like Eclipse debugger for java, or do I have to go poor man's solution and use REPL and print statements to trace bugs?

If latter, I'm skeptical if the benefits of functional paradigm tops the primitive/lack of tooling? After all, what makes Java so good is not the language, but the excellent tooling to aid the coding, refactoring and debugging. Only the fact that clojure shows obscure java stack trace instead of translated error messages to spot the problem puts me on toes.

I can't help but get impression that clojure ecosystem is incomplete, and using it in production would know more troubles than benefits. Imagine a newcomer debugging a bug from clojure someone else has written, without proper tooling to step in the code.

I really want to learn this language and hope my impressions are wrong. By syntax wise, the language feels comfortable due it's simplicity and uniformity.

4

4 Answers

7
votes

I use the awesome debugger found in cider (emacs), and I heard that cursive (intellij) has a very nice debugger as well.

Personally, I find clojure no less then great for production code. I can connect with the debugger to a production process (if its needed), debug and redefine things to have quick fixes without ever taking the process down or reloading. I find the tooling wonderful, emacs is insanely powerful and you have refactoring (if you really need it, i hardly ever use it in clojure as opposed to java) and almost anything else you need. Even stack traces are shown very well using cider.

For me, right now, the thought of writing production code in java gives nightmares.. :)

7
votes

emacs has debugging, IntelliJ+Cursive has debugging, Eclipse, and others. A google search for any of these will yield more information. I use intelliJ and its debugger is full featured and nice, allowing you to put breakpoints even in clojure and java core code.

Initially I used a debugger with clojure, and every few months I pull it out when the problem seems to warrant it. But debuggers are not all they are cracked up to be. For example, when dealing with async code, a debugger is not very helpful. REPL-driven (and test-driven) development is a big advantage over the traditional "compile and run" process that a language like java requires, and almost eliminates the need for a debugger.

Clojure stack traces are just java stack traces, with clojure code mixed in. If a java stack trace doesn't make your eyes bleed, a clojure one shouldn't be much worse. The problem with stack traces seems to be that people don't actually read them.

I would disagree with your comments about Java; Java has many positives, first and foremost its ubiquity resulting from "write once, run anywhere," some very good core libraries, and more. But refactoring and debugging are (almost) completely unrelated to the language itself. And I'd say Clojure's tooling is pretty simple. Dependencies are handled easily. In short, you don't choose a language because of a debugger, though the editors/IDEs mentioned above have some good ones available.

We run clojure on huge, major production systems that span the world, and many other companies do too. The java ecosystem provides a particularly well suited host for clojure for critical systems.

Imagine a newcomer debugging a bug from clojure someone else has written...

A newcomer learning clojure and debugging some code may in certain situations want to use one of the debuggers mentioned above, but in most cases he or she will be better served by understanding what's going on first, developing a closer familiarity with clojure, and only then resorting to a debugger.

6
votes

Clojure has multiple debuggers available, as well as some clever approaches to instrumenting your code.

Before coming to Clojure (from Python, Ruby, etc), I usually wouldn't bother with debuggers. But I use CIDER's debugger (Emacs) all the time and find it very useful for its simplicity and trivial setup (key sequence C-u C-c C-c). There's a nice tiny GIF demo on the CIDER project page (and shown below), and an extensive 8-minute video demo here. Since Clojure encourages small and referentially transparent functions, testing and debuggability are straight-forward for many functions.

cider debugging

The thing to notice in that GIF is that the code is being stepped through right in your actual code buffer with n, and the intermediate results are shown inline on the right. There are more features included now since that GIF was created.

Cider also has "enlighten-mode" that can show you values in-place after evaluation. Here is a nice gif example. It works similarly to debug mode where you need to turn it on (M-x cider-enlighten-mode) and then eval and run the function.

Beyond that, there's also the Sayid debugger and profiler. The video there is a really detailed walk-through. It's a bit complex but seems quite powerful and also gets into profiling. Bill is obviously dedicated to making it work well in Emacs, but there are also efforts to make it work with Vim/Fireplace; see vim-sayid.

This is a nice debugging article that mentions and the ol' println approach, as well as spyscope and clojure.tools.trace, other useful approaches.

You can go even beyond spyscope with datascope to get graphical and well formatted debugging visualizations.

0
votes

In Clojure, you don't need debugger like in static languages. Just use REPL, eval any expression from you editor and get answer immediately. Start to talk with developing system from the first line of code by run it in REPL. It is completely different philosophy. You need editor with hotkeys to send code to the REPL. Don't write code in REPL like in other langs. The best talk about it from Stu Halloway https://www.youtube.com/watch?v=Qx0-pViyIDU

Also, you can print value in any line of code using tap> function from clojure.core. Example of that is here: https://gist.github.com/mikeananev/346cd6084d98381e7cf1378ef423a56a