In order to see why all this is helpful, let’s start with some simple functions that return either a result or
Chaining multiple of these functions and checking for undefined can lead to rather verbose code.
Of course there are multiple ways around this tour-de-france of nested if-statements including early returns, exception handling and a functional encoding using the Maybe monad or Option types (for the Scala people out there).
Today we will look at some encoding that is similar to the last mentioned solution – with the goal to support a nice syntax.
To give a preview on how the solution to the example looks like, we start rewriting the two functions
As it can easily be seen we just used the function
some to flag the result correct and
otherwise return the value
none (We will see how both are defined in a second).
The chaining of the method calls now can be expressed in terms of for-loops:
Pure awesomeness. Let’s see how this can be achieved.
At first we create some constructor function
Option that takes an optional value to store.
Whether or not a value has been passed is saved in the property
this.some. The true ‘magic’ then happens in the prototype function
iterator which is called internally by for-loops and spread operators.
It basically works the same way as returning a singleton array
some(x)and an empty array
So let’s dig into this a little bit deeper and redefine
none in terms of arrays:
The amazing fact: The above version is of course backwards compatible to ES3. And it also works out of the box with the ES5/6 collections and libraries such as underscore.js.
Refactoring code like
return is_true ? result : undefinedinto
return is_true ? [result] : allows callers to write programs in a more functional way without loosing backwards compatibility.
The solution is an encoding inspired by scala’s for-comprehensions. Sadly ES6 does not desugar “for-loops” into plain method calls and anonymous functions like in scala. So hacking the for syntax is rather restricted.
The easiest encoding using empty and singleton arrays for
some offers the advantage that using list comprehensions the result is automatically wrapped up in the correct type.
yields nothing since
for is a statement and not an expression.
Nevertheless, I think both ways (the
Option function and the array encoding) offer great advantages over the common imperative idiom.