Note: This is a mult-part series! You're going to benefit the most following it from the very beginning, since we re-use code and concepts from previous posts to build our newer ones.

Back to Basics: Functional Programming

I found this post on Reddit recently, where the asker was struggling with their understanding of implementing functional programming fundamentals without the use of a helper library like jQuery or Underscore.

I think wanting to learn the inner workings of these types of functions is extremely helpful. The most successful programmers should be able to describe to others what every function is doing -- especially helper functions that come packaged in a library.

Why Each

For the purposes of this post, we're just going to assume that these functions only work on arrays. They don't -- functions like each and reduce can work on objects as well, but we're going to simplify things.

You have an array, pets, which contains a list of different pets you can have:

var pets = ['dog', 'cat', 'parrot', 'hamster', 'lizard']

You want to count the number of letters in each animal's name, so you create a function called count which does this:

function count(string) {  
  return string.length;
}

But calling count(pets[0]), count(pets[1]), count(pets[2]), etc. becomes extremely time consuming. So now you want to somehow call count on ALL of the items within pets. You also want to make it so if you add many more animals (or remove a bunch of them) from pets, the function still works properly.

You might think to create a function like so:

function countAllPets() {  
  for (var i = 0; i < pets.length; i++) {
    count(pets[i]);
  }
}

That's great, but now you also want to simply print their names to the console with another function, print:

function print(string) {  
  console.log(string);
}

Now if you want to call this function, on your pets array, you'd have to write something like this:

function printAllPets() {  
  for (var i = 0; i < pets.length; i++) {
    print(pets[i]);
  }
}

But this isn't very efficient, we'll end up writing a ton of functions that do the exact same thing (iterate over an array) and then call something else within it.

You should (hopefully) already be aware that we can simplify this a slight bit in the event that the array we'd like to run these on will change:

function printAllArray(arr) {  
  for (var i = 0; i < arr.length; i++) {
    print(arr[i])
  }
}

This makes it so we can pass printAllArray any array as a parameter and be able to run print on it.

Let's take the next evolutionary leap and allow this function to also accept other functions:

function each(arr, otherFunction) {  
  // Iterate over the input array
  for (var i = 0; i < arr.length; i++) {
    // Call otherFunction at each iteration, passing in the current element, i, and the entire array in case otherFunction needs them
    otherFunction(arr[i], i, arr);
  }
}

This second parameter of each, otherFunction, is what's known as a callback. We're having each accept another function as a parameter, so that each can call it within itself.

We just created each. Now to count, we can say:

each(pets, count)

And to print, we can do:

each(pets, print)

Additionally, we don't even need to pre-define a callback -- we can make it up on the fly as an anonymous function:

each(pets, function(element) {  
  console.log("This pet's name is: " + element)
})

In here, our anonymous function will take the element of the array and log it, concatenating a pre-determined string in advance.

Remember -- each is a bit more complicated than this, since it's also able to iterate over objects.

Next time, we'll cover map.