JavaScript without if else cascades

javascript

Never ending JavaScript. Is this a rehash of an old post? Yes it is.
But Ii it still relevant.? Well, yes it is. Very much so.

Please (re) read carefully and try and use in your production JavaScript.  In case you want it to be resilient and efficient JavaScript.

[first published 2011 Sep 15]

So you are proficient in JavaScript.  Perhaps a wizard? A beginner? An JavaScript Ninja maybe? Awesome.  Question for you. Do you enjoy writing longer if else cascades? Or the long ones?

Never mind that (for a moment) now admit to yourself, how many times in your ninja turtle life have you written this kind of JavaScript code.

We can try and wax cynically on the philosophical cons and pros of the above code. Some of you, I am sure will immediately label this example as an “obfuscation”, which can be nicer coded with the ternary “? : ” operator. True.

But only to a certain level of complexity. While more imaginative, or should we say better, coders will see the potential for some serious silent bugs and will suggest some clever if else coding idioms. Some will simply mandate the switch statement instead of if else cascades. If they can replace them cascades with switch, that is.

But inevitably, code changes and grows, and very soon none  of us are satisfied with the ever growing amount of very carefully placed if’s and else’s. At this point 99% of coders will simply persevere through  these ever longer if else cascades. Test, debug, test etc until it works. And then leave it for somebody else to worry about in the future.

But I am not satisfied with this. I do not like code sprinkled with time bombs. Every medium complexity if else cascades starts shaping up as a potential source of future trouble. Not to mention the long ones. Or really (really) long ones. This is not resilient programming. Or scalable.

This is where dbj.cond() comes as useful. Here is an arbitrary real life example. And also first as a wrong usage  example. No this is not an obfuscation. Persevere with me please.

Please follow this link for details about dbj.cond().

Well I am sure now a lot of ninja’s from my honorable readership can understand how cumbersome the above will look in standard if-else-if-else lingo, compared to above. And yes few more have also spotted an “sorcerers” code here. A “witchcraft”. What is going on above? Is there a mistake somewhere perhaps?

Above we have introduced “code as arguments” idiom. Expressions (instead of single values) which are first executed and rendered into a single value.

Ok, so what? What does that mean, to have code as arguments? Maybe you have not thought of that before, but regardless of this being a surprise to you, the source of evil is: when is that code in place of arguments executed? Is it all executed, then results kept in some hidden temporaries and then used inside the function which is called ( in this case dbj.cond() ) ?

Well almost right. Expressions given as arguments, are executed and results are assigned to arguments of the function call.  All the expressions given as arguments to function calls are executed, before program flow actually enters the function called.

So. The above code will be first executed and will yield to this before dbj.cond() gets called!

That is a real picture. All of expressions executed and all replaced with a single value, to act as function argument. In above simple example perhaps not a big deal, but in some other scenario a very big deal indeed. You do not want code to be executed, even if not on the programs logic path!

So, as they say, be judicious with this pattern. Use dbj.cond() for clean but complex logic coding, but by no means do not get carried away with your “discoveries” and inventions of some clever usage patterns of dbj.cond().

And solution to the above problem is coming next.

We will also use another real life  example in the same time : Handling the key, user has typed. dbj.cond() in case you haven’t noticed will also take arrays (if given as arguments) and look inside them for comparison . Which is also yet another advantage vs the standard if() statement. Here is dbj.cond() way of coding that. Including the solution for the above problem as well: how to have code as arguments, but executed only if required. With lambdas as arguments, of course.

Above is also and in the same time a nice little function dispatcher.

Now this surely would be more difficult with standard if-else-if-else cascading. For 90% of JavaScript population much more difficult and error prone actually. And there is something more “hidden” above. The solution to the problem of “expressions as arguments”.

Look carefully. Above we do not execute anything given as arguments. We simply put the code in anonymous functions (aka ‘lamdas’) and return one of them. And then the function returned we simply call upon returning it from dbj.cond().  This is a way to avoid the execution of any of the code given as arguments to the dbj.cond().

So. As complexity grows dbj.cond() becomes more and more useful. And vice versa. And who can guarantee that any of the production code will not grow in complexity?

I admit, I nicked the concept form LISP (cond …). But then JavaScript power of expression did the rest of the magic.

Enjoy.

Leave a Reply