Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Beginners Guide to Functional Programming: Part 2

DZone's Guide to

Beginners Guide to Functional Programming: Part 2

An awesome introduction to functional programming in-depth and easy to follow along. Read this article first before you voyage forth into Scala programming.

· Java Zone
Free Resource

Try Okta to add social login, MFA, and OpenID Connect support to your Java app in minutes. Create a free developer account today and never build auth again.

This article is a continuation of part 1, where we introduced why we should even bother with functional programming in the first place. 

Quick Glossary of Terms

Mutable: You can set a variable again and again. Opposite of a constant. Mutable state means I can set the variable to something else later.

var age = 37; // cool age = 38;
const age = 37; // "TypeError: Assignment to constant variable. age = 38;

Side Effect: When you call a function and it modifies a variable outside its scope.

var age = 37; var birthday = () => age++;

Imperative: Programming languages where you describe how to do something, use a lot of mutable states, and are typically associated with non-functional programming.

Higher Order Function: When you pass a function to another function. JQuery’s click, event handlers, etc. are examples:

// notice first and only parameter passed to click $( "#target" ).click(function() { alert( "Handler for .click() called." ); });

What Is Functional Programming?

The simple definition of Functional Programming is writing functions like you’d write Algebra and instead of changing data, you get new data.

You write pure functions and try to ensure your data is as immutable as possible.

Why is Functional Programming This Way?

Predicability.

In math, if I add 1 + 1, I know that the answer is always 2. That’s predictable.

It’s also helpful for concurrency (doing many things at the same time like in multi-threaded programming).

In Algebra, you “solve for x”. In math, they’ll say x = 1 + 2. If you’ve done Algebra, you know x is equal to 3. In code, it’d be:

function getX() { return 1 + 2; }

The important thing here, which may seem painfully obvious, is if you call getX(), you’ll always get 3 back.

If you’ve done any non-functional programming, you know that’s NOT always the case. Observe.

function getX() { return 1 + 2 + data; }

What is X now? No clue. If someone sets data to 0, then it’s 3. If someone sets data to ‘0’, then it’s ’30’. That, my friends, is not Algebra. You can no longer “mathematically prove” getX returns 3. You have to know the history of what happened before, or even while, you call getX.

Lastly? No errors. If your functions are truly pure, you don’t get thrown exceptions. You only need try/catch for particular nasty/scary sections of your code, 3rd party code, or known mutable sections like database calls or text file read/writes.

Once you can start depending on functions that don’t break, you can start to build more resilient and testable applications.

Pure Functions

Academic Pure Functions

You do this through pure functions: Functions that always return the same result with certain parameters, no many how many times they are called. You saw above the first getX function had no parameters. Let’s give it some:

function add2(a, b) { return a + b; }

Assuming the function is always passed non-decimal numbers, you’ll always get the same result.

add2(1, 1); // 2 add2(3, 5); // 8 add2(0, 0); // 0

In fact, you can pass in strings, arrays, objects, and even Errors, changing the order of the parameters, and Chrome has improved the pureness of the addition operator, unlike in the past.

Real World Pure Functions

Let’s take a look at the real world. In a Node project I’ve worked on, there are 2 core problems pure functions have helped me with. Specifically using Predicates and Higher Order Functions. DAT POCKETWATCH, THO.

Predicates

Predicates are pure functions that always return true or false and are used for 2 things: To assert obvious things, and used as building blocks to make more ambitious, complicated assertions.

While available in any language, and highly sought after in languages with dynamic typing, strong typing can only take you so far. Eventually you’ll create a domain model, aka “your version of the world described in code” that you want to prove. Like proofs and postulates in Geometry, you start small, and work your way up. The stronger your simple predicates, the stronger your composed predicates become. Composed just means more complex functions made from many smaller functions.

Reminder: These are not unit tests. They’re just functions.

Node Predicates

In my Node API’s, I make assertions about the data you send me for creating a new user. I use predicates to verify the POST variables you send over the wire as JSON are legit. Easy, right? Not in JavaScript. It has no types, nor runtime support for type mis-matching.

Strongly-typed languages still have to deal with parsing unstructured data, and in-memory, already parsed data that they have to make some assertions, NOT assumptions, against. Thus, predicates are still applicable both at runtime as well as in tests.

Let’s start small with some good news: There are already some wonderful, low-level predicates written for you in a library called Lodash. Others like Underscore, Ramda, and 1-liners exist as well. This is important, so we don’t have to deal with the differences between null and undefined, == and ===, nor ever care again.

Here is the REST call’s signature:

URL: https://some.server.com/api/user

Type: POST

Body: Object which has firstName, lastName, EID, adjustmentNumber, activated, creatingEID, and roleID.

Description: When you want to create a user, send their name, company ID, who’s creating this user, what role they are assigned to, whether they are start out activated in the system, and the adjustment number for tracking purposes.

Building the Predicate Reverse Pyramid

Let’s start small and work our way up. Lodash will give us the firm foundation. Strong-typing people, bear with me as we work our way up to higher level predicates.

In Node, your client requests come in this object called Request, whether you’re using Express or Restify. For PUT and POSTS, it should have a body object that has all the JSON the client sent us.

… wait, “should”? No no, strong people, strong, MUST! MUST OR AND DEN OR U SHALL NOT PASS!

Notice, in JavaScript, a null or undefined request is still a worthless request. We gotta have strong basics, remember. Lodash has the opposite of what we need, a _.isNil predicate (is something null or undefined). We need the opposite. Let’s create our own.

var notNil = _.negate(_.isNil);

Cool, let’s test it. I’m just using JSBin.com to play around, but you can use Node & Mocha, Jasmine, Tape, or Assert locally, whatever works for you.

var notNil = _.negate(_.isNil);
console.log(notNil());
// false console.log(notNil(null));
// false console.log(notNil(undefined));
// false console.log(notNil(''));
// true console.log(notNil({}));
// true

The first 3 are important. Nothing, which in JavaScript is undefined, we interpret as nil. The 2nd two, being explicit, also are nil. An empty string and an object, the basics of what we get in JSON from clients, are legit. Next up, the body:

var isThereAndHasBody = (req) => notNil(req) && notNil(req.body); 
// or function
isThereAndHasBody(req) {
return notNil(req) && notNil(req.body); 
}

While both functions basically do the same thing, the declared (or named function) is hoisted, defined when the outside script is run, and has a this. The last part is the impure part; a function’s this can change based on who calls it, where, and how using things like bind and Function.call/apply. As an ex-Flash Developer, I saw this take 6 years to solve. In JavaScript, half avoid it entirely whereas others clamor for binds all over the place in ES6 classes.

While your first temptation may be to omit the notNil(req), there are 2 things I want you to note here. First, if we didn’t place it there, our function would return possibly 3 values: true, false, and an uncaught exception if you passed in a non-object or null/undefined. A predicate returns only true or false, not true, false, and boomz.

Second, notice what the function asserts. That a “request is actually there, AND has a body”. That predicate is asserting that it’s a valid object, and that object exists.

“But why can’t we just control the order you call the functions, ensure we’ve already done that check before hand?”

Then the function is no longer pure. Like the getX example way up above, you have to know the history.

There ARE other options, though, like caching the value via memoize, a safer way to get properties via a safe get, or your own controlled predicate via flow.

They hardcore mode, though, so let’s keep it simple.

Next up, verifying the firstName is legit:

var validName = (o) => notNil(o) && _.isString(o); 
var requestHasValidFirstName = (req) => isThereAndHasBody(req) && validName(req.body.firstName)

We create a validName predicate and then use it plus our previously created isThereAndHasBody predicate together.

console.log(requestHasValidFirstName()); 
// false console.log(requestHasValidFirstName({body:{}));
// false console.log(requestHasValidFirstName({body:{firstName: new Date()}));
// false console.log(requestHasValidFirstName({body:{firstName: ''}));
// true console.log(requestHasValidFirstName({body:{firstName: 'Jesse'})); 
// false

This is the part where you start to realize, “I thought predicates were going to be a piece of cake, asserting uber obvious stuff, and yet… subtle bugs creep in.” Can you spot it? A firstName of ” is not a valid first name. Let’s modify our validName to be more stringent.

var validName = (name) => { return notNil(name) && _.isString(name) && name.length > 0; }; 
// ... console.log(requestHasValidFirstName({body:{firstName: ''})); 
// false

Now we’re talking. Let’s re-use for the lastName:

var requestHasValidLastName = (req) => isThereAndHasBody(req) && validName(req.body.lastName); console.log(requestHasValidLastName()); 
// false console.log(requestHasValidLastName({body:{lastName: ''})); 
// false console.log(requestHasValidLastName({body:{lastName: 'Warden'})); 
// true

Much easier, all I had to do was copy pasta the firstName predicate, and change req.body.lastName. Notice at this point you’ve been composing functions within functions. Your notNil uses Lodash. Your validName uses Lodash + your notNil. Your isThereAndHasBody uses your wrappers over Lodash, etc. You repeat this process to build out the rest of the predicates you need as well as create predicates that assert higher level statements about your data model.

The key point not to miss is that they are ALL pure functions. No matter what order you call, nor what parameters, you’ll always get the same result. You now have a ton of code that is dependable. (Yes, you should still unit test them, before you write them if you can).

Array Comprehensions

Now that you have a bunch of predicates, you’ll want to apply them all at once. Most languages deal with lots of things in a list. In JavaScript, that’s an Array. List Comprehensions are basically like for loops, except they act like a predicate on an array, items in the array, or both. I’ll show a few first, then we’ll use them with our predicates above.

Humble for Each

If you’ve done a loop on an array, you often will use the for each:

var list = ["uno", "dos", "tres"];
for(var i=0;
i<list.length; i++) { 
  console.log(list[i]); 
}

She’s been one of the core workhorses in my career. Here’s the functional equivalent:

_.forEach(list, i => console.log(i));

You’ll notice most all array comprehension methods follow a similar function signature of the array to operate on, a function to run on each item of the array, and will return something. “Yo, loop through this thing, and and call this function on each item”.

Every

Going back to our validation predicates, how do we know if they all worked? Lodash’ every will loop through all the things. If even one of the callbacks returns false, then every will return false. If all the things return true, then every will return true.

A simple example:

var list = [true, true, true]; 
var result = _.every(list, function(item) { return item; }); 
console.log(result); 
// true

Or the shorthand version:

var result = _.every(list, i => i);

All fat arrow functions do an implied return for you. So not this:

_.every(list, i => return i)

but this:

_.every(list, i => i)

Cool, now let’s apply to our validation predicates the same way:

var validRequest = (request) => _.every([ isThereAndHasBody, hasLegitFirstName, hasLegitLastName, hasValidEID, validAdjrNumNumber, validActvIndNumber, validCreatingEIDNumber, validSSORoleID ], predicate => predicate(request));

We pass in a request object (in Express/Restify, it’s an Object which has a params for GET’s and body for POST’s, etc). We give it a list of functions which, hopefully, return a true. The last parameter is our callback that takes the predicate, passes the request to it, and returns the result. “Yo dog, I got this request from node, can you pass it to each of these functions, and if they all say true, lemme know, else, just heck with it, false”.

Whether we pass empty, an object or even an empty body, she’ll always report false:

console.log(validRequest()); 
// false console.log(validRequest({})); 
// false console.log(validRequest({body:{})); 
// false

but if we pass the right stuff:

console.log(validRequest({ body: { firstName: 'Jesse', lastName: 'Warden', eid: 'aaa111', adjrNum: 1, actvInd: 1, cretNum: 'aaa111', ssoRoleID: 1 } })); 
// true

She’s good to go. Now we can validate all requests with assurance when they come in. Another thing, these things are cake to unit test. Here’s some Mocha examples:

it('test is a valid name', function() { predicates.validName('test').should.be.true; }); 
it('blank is not a valid name', function() { predicates.validName('').should.be.false; }); 
it('numbers are not a valid name', function() { predicates.validName(1).should.be.false; });

Some

Let’s cover 3 more so you can refer to them later in the post where we’ll use them.

In the application I’m building on at work, we do the same search against multiple databases looking for a match amongst a lot of old data. If even 1 out of the 3 searches finds something, that’s great! When I get a match from a search, I return it like this:

{ success: true, result: [... the data I found] }

If I didn’t find anything, I get:

{ success: false, error: ... reason why it didn't find anything }

Now, using old sk00l, imperative techniques, I’d go:

var searchResults = [ {success: false, error: 'no id matches'}, {success: false, error: 'no id matches'}, {success: true, result: [{id: 1, name: 'Cow'}, {id: 1, name: 'Moo'}]} ]; 
function foundAMatch(searchResults) {
  var len = searchResults.length; 
  for(var i=0; i<len; i++) { 
    var o = searchResults[i]; 
    if(o.success) { 
      return true; 
    } 
  } 
  return false; 
} 
console.log(foundAMatch(searchResults)); 
// true

The new way is to use some (sometimes called any):

function foundAMatch(searchResults) { 
  return _.some(searchResults, o => o.success); 
}

If any of the callbacks return true, then some returns true. If all of them return false, then some returns false. Now when I make a bunch of Promise calls, if even 1 of my searches succeeds, I can see if it found a match in a pure way. How do I get it?

Filter

Filter you give an array, and gives you an array back with only the items you want. It filters things in and out. Here we can filter some cows:

var animals = [{type: 'cow'}, {type: 'dog'}, {type: 'lizard'}, {type: 'cow'}];
function onlyCowsUpInThisMug(list)
{
  return _.filter(list, function(item)
  {
      if(item.type === 'cow')
      {
          return true;
      }
      else
      {
        return false;
      }
  });
}
console.log(onlyCowsUpInThisMug(animals).length); // 2

Or the more succinct, ES6‘ish way:

var onlyCowsUpInThisMug = (o) => _.filter(o, o => o.type === 'cow');

“Yo, take this list, and take out the things that aren’t cows, kthxbai.”

Using our search above, I can get only the successful searches:

var successfulSearches = (searchResults) => 
_.filter(searchResults, result => result.success);
console.log(successfulSearches(searchResults).length); // 2

Reduce

Cool, there’s just one thing left, getting combined list of those searches. However, they’re all objects of success and result… I just need the result, and I need all of them combined. We’ll use reduce to do that.

Reduce is used to take an array, and give you a new one with reduced data. “Reduced” is subjective, however. You can reduce an array to whatever you want. You could reduce data, add new data, or return the same thing, up to you. Unlike other list comprehension methods, reduce takes an optional 3 parameter, something called the accumulator, to accumulate, or collect all the results. This is, like most things in Functional programming, an array.

In imperative, you’d use nested for loops (or some for prop if you take this stupid whiteboard/fizz buzz tests people give you in dumb, coding interviews):

var searchResultsThatWorked = successfulSearches(searchResults);
var resultsLen = searchResultsThatWorked.length;
var accumulated = [];
for(var r=0; r<resultsLen; r++)
{
  var searchResultItem = searchResultsThatWorked[r];
  var itemsLen = searchResultItem.result.length;
  for(var i=0; i<itemsLen; i++)
  {
    accumulated.push(searchResultItem.result[i]);
  }
}
console.log(accumulated.length); // 2

Vars everywhere. Let’s use reduce instead:

var accumulated = _.reduce(searchResultsThatWorked, 
(accumulated, searchResultItem)=>
{
  return accumulated.concat(searchResultItem.result); 
}, []);
console.log(accumulated.length); // 2

You’ll notice that I stored the results of reduce in the accumulated variable. However, I used an empty array as the 3rd parameter to reduce. While pure, you could set that 3rd parameter to another variable if you wanted to. We just wrap that reduce in a function called reduceAllSearches.

var reduceAllSearches = (searchResults) => {
  return _.reduce(searchResultsThatWorked, (accumulated, searchResultItem)=>
  {
    return accumulated.concat(searchResultItem.result); 
  }, []);
};

Yes, for the first 2 years it’s hard to read. With practice, your brain adapts to pick out the callback from the call from the array. I’m not being sarcastic for a change, I’m serious. When I first saw this stuff, even before ES6 fat arrow functions, I was like “What a mess”. You’re welcome to use named functions with more clear variable names to help readability. The point here is to use pure functions with arrays via list comprehension methods.

Combining Comprehensions

Putting it all together:

if(foundAMatch(searchResults))
{
  var foundResults = reduceAllSearches(searchResults);
  // ... send foundResults to client
}

Checkers

There are 3 problems, sadly, with our above carefully crafted predicates.

  1. If it returns false, we don’t know which one failed, nor why.
  2. If we don’t know, then we can’t tell the user how to fix their request.
  3. The lack of exceptions in pure functions, which at first you thought was cool, makes it hard to know who failed when they are so deeply composed. (Smartasses will go “well, perhaps if you unit tested them, you’d know”)

I’ll show you how to write checker functions, a trick taught to me by Chris Petrilli. Checkers are like predicates, except instead of always returning true or false with no exceptions, they always return an array. If the array is empty, great, no errors. If it has even 1 item in it, it’s the reason(s) why the predicate failed.

For small checkers, this is obvious stuff, and pointless in strongly typed languages: “Yo dog, Date’s aren’t a String”. For higher level stuff, and across strongly typed boundaries (HTTP requests, database, parsing data, etc), they are immensely helpful in debugging, both your own code and others. They also take a lot of work, whether you’re a n00b at functional programmer, or an ace.

Let’s add some to our above predicates to see how they work. To do that, we need to create these new type of functions easily. In strongly typed languages, you can just create an interface. For dynamic ones, we’ll take advantage of functions being basically Objects and create special ones by adding data to them we need.

Let’s create something called a validator. It’s basically a predicate, but if it returns false, we can inspect it and snag a descriptive error message of it as to why it failed.

var validator = (errorMessage, funk) =>
{
var predicateWrapper = function()
{
return funk.apply(funk, arguments);
};
predicateWrapper['errorMessage'] = errorMessage;
return predicateWrapper;
}

We wrap our predicate, and add the error message to it. Let’s use with our validName predicate:

var nameValidator = validator('Not a valid name, Holmes.', validName);
console.log("no name:", nameValidator()); // false
console.log("Jesse:", nameValidator('Jesse')); // true

Ok, seems to work exactly like a predicate. But check this out:

console.log(nameValidator.errorMessage); // "Not a valid name, Holmes."

Cool, so if it fails, people can look at that errorMessage to see why. Those of you with OOP deep in yo bones are probably like:

Yo, why can’t we just go validName.errorMessage = “Not a valid name, Holmes” and call it a day?

That’s not a Pure Function, brah! But sure, you could. As you use more list comprehensions, you’ll see your “default mode in life” is to start creating functions for everything so you can use them with things that expect functions. That’s why I created notNil up above instead of using !_.isNil.

You don’t use validators directly like you use predicates, they are just a function that houses an error message so when they boom, people know why. Those people in this case are the checkers. Let’s make the function for that:

var checker = function()
{
  var validators = _.toArray(arguments);
  return (thingYouWantToValidate)=>
  {
    return _.reduce(validators, (errors, validatorFunk)=>
                    {
      if (validatorFunk(thingYouWantToValidate))
      {
        return errors;
      }
      else
      {
        return _.chain(errors).push(validatorFunk.errorMessage).value();
      }
    }, []);
  };
};

Whaaa… ok, in a nutshell please?

“Yo, I’m going to send you some predicate functions I made. If you could give me a function back that runs them and gives me an empty array when they work, or errors in that array for the ones that don’t.”

We’ll start with 1, our name validator.

var checkName = checker(nameValidator);
console.log(checkName()); // ["Not a valid name, Holmes."]
console.log(checkName('Jesse')); // []

Make sense, now? Our checker is smart enough to go, “If this thing returns false, look for that errorMessage”.

Let’s do something more sophisticated, and combine our request verifier. Let’s create 3 new validators, and throw ’em in a checker:

var isThereAndHasBodyValidator = validator('No body or invalid request.', isThereAndHasBody);
var firstNameValidator = validator('Not a valid firstName.', hasLegitFirstName);
var lastNameValidator = validator('Not a valid lastName.', hasLegitLastName);
var checkNameRequest = checker(isThereAndHasBodyValidator, firstNameValidator, lastNameValidator);

The checkNameRequest will first verify it’s an object with a body, then verify both the first and last name are valid. For the ones that fail, it’ll put the errorMessages in the array, and when all done, send that array back. Full of errors for invalid, empty for valid:

console.log(checkNameRequest()); // ["No body or invalid request.", "Not a valid firstName.", "Not a valid lastName."]
console.log(checkNameRequest({body: {
  firstName: 'Jesse'
}})); // ["Not a valid lastName."]
console.log(checkNameRequest({body: {
  firstName: 'Jesse',
  lastName: 'Warden'
}})); // []

Once you put all your predicates in a checker for the request, you can then use it to verify if the request is good and if not, both debug it yourself, as well as send it back so whoever is calling it knows what they did wrong.

var errors = checkRequest(req);
if(errors.length > 0)
{
  // ... return errors
}
else
{
  // ... use the request
}

Conclusions

You’ve seen how pure functions allow your code to be predictable, easily unit testable, and prevent you from having to use try/catch to handle errors. Composing many of them together allows you to build a more solid code base.

You’ve seen how you already use higher order functions all over the place in the existing programming you’ve probably already done. Passing functions to other functions is common place.

You’ve seen how using list comprehensions allows you not just easily consume data from arrays, but also using them as tells to call and interact with many other pure functions.  In many cases, it results in less code compared to the imperative equivalents.

You’ve seen how predicates allow you to practice writing pure functions, validate your inputs, and give you great runtime feedback when combined with checkers.

Most importantly, you’ve probably seen how you can use some functional programming in your existing code base.

In a future post, I’ll refactor some existing OOP code that illustrates the bubbling problem you run into using pure functions (forcing functions higher up to store the actual mutable data). I’ll also showcase how this larger amount of pure functions can simplify your unit tests, and how it changes your usage of mocks. Finally, I’ll show some small tips on how to more easily test some of the async parts of your code.

Build and launch faster with Okta’s user management API. Register today for the free forever developer edition!

Topics:
functional programming ,functions ,design ,development

Published at DZone with permission of Jesse Warden, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}