On Sat, Jul 2, 2011 at 8:19 PM, Luc Prefontaine
<lprefonta...@softaddicts.ca> wrote:
> Were did you find the link between functional languages and close proximity of
> errors ? That's a language design decision. You may want to use assertions
> on your fns to validate inputs. That sould improve your ability to track 
> errors
> before they carry things too far from the spotwhere it failed.
> I would not trade this for systematic exception reporting.

Sorry if I wasn't clear about this.  One time I was rereading a book
about the art of debugging (I think it was this book:
http://www.amazon.com/Why-Programs-Fail-Second-Systematic/dp/0123745152),
and realized that the main theme of the book is that the #1 reason
that debugging is hard is that most bugs result from some sort of
mutation of state in one part of your code that inadvertently violates
some assumption or invariant you had in your mind.  But your program
doesn't crash right away, it keeps quietly chugging along with that
corrupted state until some completely separate portion of your program
tries to do something with that data that no longer makes sense and
KA-BOOM.  But the line your debugger shows you just shows you where
the crash happened; it can't show you the series of steps that led to
the corruption of state that actually caused the crash.  Thus, you
need to do a lot of detective work and step through the program.  This
is precisely why, for example, most programmers will gladly pay the
performance penalty for bounds-checking on array reads and writes --
it's incredibly valuable to have your program crash where the problem
actually occurs, rather than continuing for a while with spurious
values or corrupted memory and getting a delayed crash with no clear
connection to the cause.

I had a personal a-ha moment when I read that, which made me realize
that one of the reasons I enjoy functional programming so much more is
that this class of bug just doesn't happen.  Generally speaking,
crashes have good locality with respect to the flaw in the code that
causes them because there's no "state" to get corrupted and eventually
cause a delayed crash.

Of course, often the hardest bugs of all to find are the ones that are
the result of deep logical flaws.  The program may be an exact
implementation of what you had in mind, but what you had in mind
doesn't quite accomplish what you expected it to.

And that's the problem I have with some of Clojure's core functions --
they can turn a blatant mismatch (between a function's input
requirements and the inputs that actually get passed) into a deep
logical flaw.  The get example I raised is a perfect example of this.
When I passed a transient set to a function that used get, I
reasonably assumed that transient sets implement whatever interface
get requires.  But rather than raise an error because the object
didn't support the desired interface, get just returned nil -- which
is the exact same value that is returned in ordinary usage when you
test whether something is in the set and it isn't!  So now, I have
sets that are quietly being passed around, and returning sensible
values but behaving as if they don't have any elements.  What should
be an easy bug has turned into a deep logical flaw in my program.
Everything appears to be working, but my program generates completely
bogus outputs because at some stage of its processing it tested for
membership in a set and got back nil for something that was actually
in the set.  This is the kind of thing that is a real nuisance to
track down, requiring detailed detective work and a careful analysis
of the entire chain of logic to find the spot where things actually go
wrong.  Given that get creates the illusion of working even when it
doesn't, I fail to see how a pre or post condition in my own code
could have picked up on this or validated the input, short of having a
deep understanding of all the interfaces required by every core
function and testing every input explicitly for support of those
interfaces (in which case, I might as well be using a statically typed
language).

-- 
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

Reply via email to