On Mon, May 27, 2013 at 5:39 PM, u1204 <d...@axiom-developer.org> wrote:

> The REPL is your best friend. You can "hand execute" small pieces of
> code to test your assumptions.
>
> Common Lisp systems have wonderfully powerful trace functions allowing
> arbitrary conditions and actions.
>
> I haven't seen anything like that in Clojure yet.
>

What about add-watch? Can be used with any of Clojure's mutable-value
containers -- atoms, refs, agents, vars. If one is getting set to an
inappropriate value, or you suspect it is, you can attach a watcher to it
that will emit a log entry anytime it gets set to a value outside its
expected range, including printing a stack trace that should include the
spot in the code where this happened.

In the case of immutable data or mutable Java objects getting scrozzled,
there's always the option of modifying the possible sites of the trouble to
log buggy behavior. For instance, if a LinkedBlockingQueue is getting
polluted with nils that are making the consumer blow up, adding before
(.offer lbq x) something like (if (nil? x) (throw (NullPointerException.)))
will move the blowup closer to the actual site of the error and give you an
informative stack trace. You might even leave that one in in production, if
the thing should (or *will*) die anyway if a nil gets in there, so your
user base's bug reports will already have a useful stack trace instead of a
useless one.

Bad function arguments? Add a :pre clause to blow up immediately with a
useful stack trace, if one otherwise doesn't show up or shows up far from
the error. Bad values getting into immutable data? Add a (print ...)
wherever it's built up using assoc or conj or what-have-you.

The only times I've resorted to a debugger myself have been with buggy C
code that trashed the stack or heap or jumped off into the middle of
nowhere and the resulting stack trace, if existent, didn't point to the
true location of the error, or give any useful hints as to where that was,
and when diagnosing and fixing deadlocks in Java code. Java dispensed with
C's ability to trash the system badly enough to not have a meaningful stack
trace (even if it's far from the real error, a Java stack trace is pointing
to something *relevant*, like a null where one shouldn't be that you can
find all the mutators of; with C in real mode it was frighteningly easy to
get no stack trace at all, just a hang, kernel panic, or BSOD, and even in
protected mode your bug could systematically destroy all of the data you
could use to diagnose it and *then* crash the process) and Clojure has more
or less ended the deadlock menace (where being able to see which threads
hold what monitors and are waiting for what other monitors was the key
debugger killer-feature that stack traces and logging weren't so helpful
with) and anything that simply hangs inside the JVM can be re-tried in the
context of (def x (Thread. #(hanging-fn args))), (.start x), wait for it to
have stopped working, (.getStackTrace x), and check out the stack trace you
get to see where hanging-fn and its callees went off the fairway and into
the trees (maybe lower x's priority before (.start x) if it wedges a core
and that would otherwise make the REPL unresponsive).

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to