Introduction
Take a look at the following piece of code. What’s wrong with it?
myAwesomeFunction = (objects) ->
isGreat = false
for item in objects
if not item.isImportant
continue
if item.isGreat
isGreat = true
break
return isGreat
Does it go through all the items? No but, man, is that break on the last line easy to miss.
What does it do? Too bad a for loop has no return value. In order to get any idea you need to look into the loop code.
Now compare it with the following version:
myAwesomeFunction = (objects) ->
return _.any objects, (o) -> o.isImportant && o.isGreat
Even if you’re not familiar with the (wonderful, by the way) Underscore.js library, you can pretty much guess that myAwesomeFunction returns true iff objects contain a great important object.
Now, you could make a (valid) point that the original function is not a shining example of super-ninja programming skills. But that’s just another thing to point out: using for loops doesn’t push us, programmers, to be any clearer. Actually quite the opposite – it stands in our way by forcing us to remember we’re in a loop and we’ve to deal with it.
*This guy may or may not have written it.*When it comes to expressing our intentions, a for cycle is a low level construct; unless you read the code thoroughly and really understand, you can’t know what the purpose of the loop is. It can filter something out or transform all the items in the list. It can signal whether a certain item is present. Frankly, for all I know it can brush your teeth and sleep with your wife.
It’s just too powerful. Too universal.
Now, in case CoffeeScript (or JavaScript) is your language of choice, chances are you’re not writing the type of software where speed is essential. Which means (or should mean, anyway) readability beats raw speed. Hands down. And that’s when functional programming saves the day.
In the next article of this series, we’ll take a look at the ‘map’ function.