On 01/31/2006 11:43 AM, Russel Winder wrote:
> I was wondering if there had been any research on the area of
> conceptualization of code structures especially control structure like
> for, "defensive programming" and errors that could provide some
> scientific input into the debate.

I believe opinionated ranting counts as scientific input
in many fields these days.  As proof, here is some of mine.

On a mail list I am on there has recently been a huge debate raging on
"defensive programming" and the fact that it is a bad thing in these
days of test-driven programming.

Wait, what?  It's wrong to write code in a style that
avoids stupid, low-level errors now?  Because the test
suite will catch them?!

[pause here while I fetch some tissues to wipe
 the flowing tears of uncontrollable laughter
 from my hopefully waterproof keyboard]

Did I blink and miss the part where we proved that
test suites were now comprehensive?  Or the other
part where we decided that the purpose of the software
was to give the test suite a good workout?

Just last month, I saw some dork on /. strongly advocating
unit tests as the sole, completely reliable method
for creating high-quality software.  When pressed,
it turned out that his only experience of programming
was in writing filters for data passing between databases
at financial institutions, a domain where unit testing
is actually a pretty good way to do things.

But they don't work everywhere -- how do you write
a decent unit test suite for things like:

  + a themeable graphical user interface
    (where the actual interface isn't defined until
     the user is running it)

  + a language parser that has to *keep working*
    even when it's sent junk
    (such as you might find when the language it
     parses is written by non-programmers)

  + a security module that has to be relied upon
    to preserve the integrity of information even
    when it's running on a hostile system

All three of the above aren't speculative or
awkward examples, by the way -- they're
essential components of any modern web browser.

Note that I'm not saying that you *shouldn't*
unit test stuff, but that it's only one part of this
nutritious breakfast of champion programmers.

And 'defensive programming' is right up there
with something I think any experienced programmer
ought to be doing, to cut out as much trivial,
low-level noise from the code as possible.

It's like a good photographer, who ought to be
able to take fewer pictures that *have* to be
fixed in Photoshop.

? An (arguably trivial) example of one
of the many issues:

In a for loop people are taught to write things like:

        for ( int i = 0 ; i < N ; ++i ) { . . . }

Let me take this specific example and treat it as a
microcosm of a larger problem in writing correct code.

Most for loops I've encountered are actually iterators
in disguise, in languages that don't do iterators very
well.  (As in: "walk through this list" or "apply this
action to everything in that regular structure".)
Consequently, the for loop is, almost by definition,
not the best expression of what must be done, but
probably the best expression of how to do it in the
language at hand.  A test suite programmer might therefore
not even realize that he's supposed to be making sure that
his code ought to be probing the output of the testee
program specifically for failing near some hidden loop's
boundary conditions.

While we're stuck with languages where the best solution
to a problem is a for loop, we're surely working with
tools that don't provide a clean abstraction of the
specific task at hand anyway.  So I think it's *vital*
in such circumstances to minimize that chances that the
bug in the code is an accident caused by using a
clunky way of expressing what we're really trying
to achieve anyway.

Hence, if I heard someone criticizing my code because I
do defensive programming (and I *do* -- I didn't spend 25
years *not* paying attention to the kinds of little things
that slip by when I'm coding), they'd have to pull rank
or a Colt 45 to get me to take it out.

And don't start me on how I think code ought to be
laid out, either.  I've found real bugs in production
code just by adjusting its spacing and indentation so
that inconsistencies become apparent in its shape on
the screen.  The Indentation Police can go whistle, as
far as I'm concerned. But that's an as-yet untriggered
diatribe.

        i < N is an act of "defensive programming" and this smothers
        potential errors in the code.

Good.  Smothering potential errors is just what defensive
programming is for.  See 'Engineering' and 'Experience'.

        In particular a large class of
        errors will lead to faults elsewhere in the code and so make
debugging harder.

'Large class of errors', eh?  Name three members of this class;
the Clone Brothers don't count as more than one.

        i != N maximizes the chance of an error in
        the code being detected by a more catastrophic failure
        associated with the code itself and therefore easier to debug.

i<N maximizes the chance that the code will work properly, without
having to spend any time debugging it in the first place.  Or are
programmers expected to support their buddies in the Debugging
Teamsters, now?

        With a modern approach to programming, i.e. massively unit test
        oriented even if not test-driven development, there is no need
        for defensive techniques and indeed they are detrimental to good
        and efficient code development and maintenance.

I do hope you're making this up, Russel.  Otherwise, once such
first-order baloney makes it into common use, we're doomed.  Doooomed!

        The for loop is a counted iteration not a bounded iteration so
        whilst i < N is a reasonable condition in a while loop (which
        represents bounded iteration), i != N is a more sensible
        expression in  a for loop as it minimizes the termination
        condition and so maxmizes the discovery of error locally to the
loop.

You know, if your job is to spend all your time looking for errors,
maybe you *will* want to have the code written in such a way as to
make them happen -- then you justified your job.  Hmmm.

So the question then is: are we writing programs so that they
work, or are we writing them so that you can run a fine-toothed
comb across their innards and pick up no fluff?

> Anecdotally some teachers and trainers are admitting that "i < N" does
> cause some students some real problems.

Aw, fuff.  Fail them, then.  Isn't that the ultimate Unit Test?

        Error is detected as part of a proper unit test so a
        defensive approach to code is unnecessary and inappropriate.

We end with this delightful rendition of 'Hail to the Unit Test'
by Squamous Epithelium and the Plooks:

   All Hail the Unit Test!
   It fixes our bugs so we don't have to!
   And shows us how to write code without thought!

   All Hail the Unit Test!
   It proves our test suites are working!
   And makes it easier for our teachers to mark our exercises!

   All Hail the Unit Test!
   So that programming can be outsourced to call centres!
   And our gadgets can become cheaper!
   If somewhat less reliable for reasons no-one understands!
   All Hail the Unit Test!

Thank you.
--
Frank Wales [EMAIL PROTECTED]

----------------------------------------------------------------------
PPIG Discuss List (discuss@ppig.org)
Discuss admin: http://limitlessmail.net/mailman/listinfo/discuss
Announce admin: http://limitlessmail.net/mailman/listinfo/announce
PPIG Discuss archive: http://www.mail-archive.com/discuss%40ppig.org/

Reply via email to