FPSK: Promises on the road to Declarative Programming

By now if you’ve been following FPSK, you’ve made it through the most difficult concepts of functional programming Immutable Data Structures and Composition. The light at the end of the tunnel is near. The last concept we'll really cover for converting our codebase is to remove any callbacks and start using promises. It’s a relatively easy transition but again its important to understand the why.

Why Promises Matter?

Promises aren’t just for your personal life, in programming they’re a huge aspect of taming asynchronous behavior. And while callbacks are certainly the default we can run into some tricky circumstances if we rely too heavily upon them.

Race Conditions and the Pyramid of Doom

More and more we’ve seen the need for concurrency within our application. Although it presents obvious benefits, hidden problems often come with this capability. Perhaps the most dangerous issue you’ll see is with race conditions, where multiple operations try and access the same in memory data.

With callbacks there is in even a time when you’ve invoked and when the callback is returned that there is no actual value representation within the system. This is what makes it highly imperative, as you then must focus on control flow or how it works.

Although race conditions are the most dangerous, the most well documented issue we see is what’s known as the pyramid of doom. The pyramid of doom happens when we have multiple callbacks with asynchronous behavior. We eventually have such nested behavior that figuring out how something works becomes much more than a chore.

function showUserProfile (userId, error) { 
   findUsr(userId, function (user) { 
      var userImage = user.url; 
      loadPic(userImage, function(pic) { 
        ui.showPicture(pic); 
      };
      getUserDetails(user.id,function(detail){ 
        ui.showDetails(detail);
      };
   };
}; 

Now lets take that same piece of code and change it to something that is more functional.

showUserProfile
    .then(findUsr)
    .then(loadUser)
    .then(UIDetails);

Not only have we created cleaner abstractions, we’re looking at solving our issue of race conditions.

But How is it Functional?

So by this point you should see some of the benefits of promises. But besides the benefits its not clear that its actually functional. One would assume that callbacks because they return functions are functional. As we recall from our early discussions, functional is about returning values. In the case of promises, we in fact always return a new object. Regardless of what then resolves to a new promise object is returned.

When I first got exposed to promises, I assumed it was a cool feature but something I could leisurely implement. But the more I find is that if you do this early on it makes it easier to think from a declarative standpoint.

As we’ve talked about earlier declarative programming is really the goal of functional programming. It’s about telling the computer what you want instead of how you want to do it. And when we’re dealing with concurrency, our goal is to accomplish as many tasks simultaneously while still ensuring that they happen in the intended order.

Declarative programming tells the computer relationships between data. With promises we no longer worry about control flow when a function will be passed back and how to handle it once its passed back. With the then method we’re basically saying regardless of what the current value is we can handle it later as a value that will be passed to another function.

Below I’ve linked to some practice exercises that should take you over the rudimentary understandings of implementing promises.

This concludes the introductory guide of FPSK. If you’re still having issues check out the Frequently Asked Questions in the Functional Programmer’s Starter Kit and sign up to hear more updates as we roll out a more advanced guide.

HD