22Mar

Boarding the “Anti-if” bus

Posted by Elf Sternberg as chat, programming

The “Anti-If” campaign seeks to educate programmers about the dangers of the if statement, which seems on its face to be absurd.  How can your program actually do anything without being able to make decisions about the data?

The focus of the Anti-If folks seems to be Java: there’s a lot of talk in the Java community about whether or not the Anti-If people are nuts, or silly, or on to something, or just on something.  However, I’ve been focusing recently on my code and trying to “anti-if” it as much as possible, and here’s what I’ve discovered:

First, if statements and if expressions are two different beasts.  An if statement creates two possible code paths; an if expression returns one of two possible values based upon an evaluation, and if you’re a good programmer, the values will always be of the same type.  (Yes, I know, I work primarily in Javascript and Python, a pair of weakly typed languages.  This doesn’t mean you can ignore typing.  If anything, you should be paying more attention to it.)  You can argue that there are still two code paths, and I agree with you, but the important consideration here is that both code paths have the same type as the ultimate result, so the testing burden is down to “does this function return what we expect it to return under all circumstances?”  By narrowing the issue down to an if expression, you constrain your test to one value of one value type.

Secondly, the use of if expressions as guard conditions is good practice; it’s basically insuring that your function meets the needs of the caller before returning the anticipated value, which is just Programming by Contract 101, and if you’re a Haskell programmer you’ll recognize a great place to use the Maybe pattern in place of null values or exceptions as signals to the caller that the function failed in some way.

Third, lots of excellent self-documenting programming techniques exist that allow you to avoid massive ‘ifs’ trees in the first place.

Recently, I was using Backbone to create an editor for the gene sequence alignment DSL we use at Spiral.   We therefore had three possible code options: create a new Aligner, edit an existing Aligner, or run an existing Aligner.  Each of these has a concrete URL associated with it, so it was possible to have separate method calls for each url by building a route association.

Instead, I had an uncomfortable mash-up of routes, all going to a single AlignerView full of if statements about “is this a launch” and “is this a new Aligner” and whatever.  I spend two days refactoring, and came out with a rock-solid concrete collection of subclasses, each of which does one thing and does it well.   There are still if expressions in there, and even a few if statements– they’re all in the code that manipulates the DOM, making visual decisions, what Haskell calls the “side effects.”  But for the most part, the risky code is now gone, replaced with a dispatch table that up front tells exactly what the code will do, and what results you will get back.

The replacement of ‘if’ statements with modern language constructs such as filters, maps, dispatch tables, routing tables, and factory functions that deliver polymorphic subclasses makes a more rich, better-documented, smaller and more powerful code base.  Like my study of Haskell, this discipline has contributed to making me a better programmer.  I recommend you try it, if only for practice.

1 Response to Boarding the “Anti-if” bus

Chris

March 22nd, 2012 at 9:49 am

Interesting blog post Elf! I am working with some existing code and I was trying to figure out “where do all the jobs get submitted???” Finally I stumbled upon a class method that had a HUGE select statement (vb.net select … case … case) which is very similar to if then else. Ugh! Who writes code like this? Now I have to study each case statement to see how to make my part fit this HUGE traffic sign. Although I don’t think we can ever get rid of all “if statements” and “if expressions” I do see them as a sign of poor architecture. Especially since we have generics and object oriented patterns. Alas, I will most likely add my case statement to the list since re-factoring this mess is way outside the scope of what I’m trying to do. The other thing that if then else blocks do is bury business logic inside code where it is difficult to decipher.

Best regards,
Chris

Comment Form

Subscribe to Feed

Categories

Calendar

March 2012
M T W T F S S
« Feb   Apr »
 1234
567891011
12131415161718
19202122232425
262728293031