

Microdesign and red flags -- or "why else-clauses are red flags" - bborud
http://blog.borud.no/2010/11/microdesign-and-red-flags.html

======
Jabbles
I hope you have some statistics that show that "else" clauses are associated
with a higher rate of bugs.

I've heard the advice (p291 Code Complete 2) is to put the most commonly
executed code-path (i.e. the one that occurs if all guards are passed) at the
top of your function, and the fails below. However I've also heard the advice
"fail fast". I suppose that a compromise could be to separate your functions
into safe and unsafe versions, with the former containing the guards and if
appropriate, calling the latter. This could be worked into the pimpl idiom
quite well.

There are obviously cases where the "else" statement is the best option.

To sum up, complexity of code is often a trade-off, and it's rarely well-
defined anyway.

~~~
bborud
No, I don't have any formal statistics on defect rates and the occurrence of
"else" and/or nested "if/else" constructs. I'll leave that to people who want
to write papers and go to conferences. I'm more of a pragmatic person.

In fact, if I did present you with those statistics you should be even more
wary because of the tendency of people to accept "research" without question.
A good example is the "research" that has been done on pair-programming. The
only conclusion I am able to reach from what I have read on the subject is
that "it depends". Of course, I can interpret what has been published in ways
that'll make the case both ways and mislead the uncritical reader to my liking
:-).

I am also wary of what I call "dogmatic programming". Just because some
"authority" says you should do something doesn't mean that it is correct or
valid in other contexts. For instance something that is a good practice in
Pascal might not be at all applicable in Lisp.

The concrete examples given in the blog posting may divert attention away from
the main point I was trying to make about "red flags" and the need to stop and
think. Indeed, most people who have commented on the posting (on Reddit and in
email) seem to get hung up on the second, "cleaned up" form of the example
given. My bad.

------
makecheck
I don't agree with returning anywhere; I think it's important to "return"
exactly once, and that includes not using "break", "continue" and "goto" to
perform logical short-cuts in most cases. (I've been writing code for 20
years.)

One reason is to have result or loop variables, which help debugging. You can
ask debuggers to _watch the value change_ , or print it, and so forth. Almost
always create variables; ignore premature-optimization "experts" who think
they've sped stuff up because they used fewer variables.

Cleanup isn't repeated. I despise "hunting" for return statements to ensure
the same 3 things always happen. Yes, maybe functions shouldn't do so much;
but if you're stuck maintaining something you didn't write, you still have to
be able to apply a change correctly.

Another problem with multiple returns is inconsistent types. I've seen code
where one person did "return false" and another did "return 1.0" in the same
function; whereas, if you're forced to type "isOK = 1.0", you'll see the
problem immediately.

And a single return point keeps overly-complex logic in your face, so that you
have good incentive to fix it. You're less likely to put off refactoring an
ugly and oversized function if you keep having to scroll through it to figure
out what a single case is doing. Less code is ultimately good for
maintainability.

~~~
bborud
I was exposed to the "single return" philosophy some time in the mid 80s and
for some years I applied it dogmatically to most of my code. However, at some
point I started looking at the resulting code and re-evaluating "why am I
doing this".

Now, an important point is that I use different languages these days than I
did in the 80s. Also, back then I didn't write a lot of (or any?)
concurrent/asynchronous code, so the programming style was far more linear and
synchronous. The things that applied to my 1980s Pascal or C programs are not
necessarily true for my Java/Groovy/C/C++ programs today.

