2

I'm using CounterClockWise to develop my first Clojure project on the Windows 7 OS. Besides javascript (which I'm not too familiar with), this is my first dynamically typed language.

The hardest part of building my project was debugging the issues I had. The technique I've been using is to sprinkle printlns in places to confirm my inputs and outputs are what I want them to be.

Compared to Java, it seems that a lot of Clojure functions accept what I'd consider garbage input and happily return nil. As a result, the runtime exception you see can come from many functions away from the cause of the problem. My point being, it can be hard to even know where to put the printlns.

And, these runtime exceptions were outputing compiled code line numbers so they weren't very informative. Most of my functions were short and side-effect free but the problem is my inputs were webpages. Sometimes the input to a function was the raw html, sometimes it was the parsed html (by enlive), sometimes it was a list of links (by using a css-like selector on the parsed html). These inputs could be deeply nested, complex structures (ie: a list of maps of maps of lists of maps) so it wasn't easy to build them up by hand. When you've got a stack trace that's not pointing to the issue, I'd pretty much have to debug half my program and figure out how to generate inputs to each part. It was pretty time consuming.

On the IRC channel someone informed me of the stacktrace library which made debugging that much easier. It still pointed many functions away from the source of the bad input, but it was still helpful. I'm looking for more techniques like this. What are some techniques I can use to debug my code better?

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356

2 Answers2

1

Since most functions in Clojure should be rather short (or decomposed to be short) and usually work without side affects, you can always try them separately from Clojure REPL or write tests for them.

Also you can use Java debugger/breakpoints with La Clojure plugin for IntelliJ IDEA - see my answer to: How to run/debug compojure web app via counterclockwise (or la clojure) for more details on using IDEA to run & debug Clojure projects.

Community
  • 1
  • 1
Tomek Lipski
  • 166
  • 4
  • Sure, in such case you've described, using a debugger from IntelliJ IDEA might be the best solution. You can also trace your function calls using clojure.tools.trace package, but if the input/output arguments are large, I don't think it would be readable. – Tomek Lipski Apr 08 '13 at 20:05
1

If garbage input/unexpected output is an issue for you when calling other functions, maybe you could restructure your code a bit so that these touch points are encapsulated in their own functions with pre/post conditions defined. e.g. http://blog.fogus.me/2009/12/21/clojures-pre-and-post/

I'm sure you could make it much more of a pleasing thing to code with a little bit of macro support. Although that might make the stack traces harder to read.

BillRobertson42
  • 12,602
  • 4
  • 40
  • 57
  • This is a useful feature, but when I lurk on IRC I get the sense that most people aren't using this in their code. So they must be doing something else to make it easier for them to debug. – Daniel Kaplan Apr 08 '13 at 21:06