Don’t Be Scared Of Functional Programming

Advertisement

Functional programming is the mustachioed hipster of programming paradigms. Originally relegated to the annals of computer science academia, functional programming has had a recent renaissance that is due largely to its utility in distributed systems (and probably also because “pure” functional languages like Haskell are difficult to grasp, which gives them a certain cachet).

Stricter functional programming languages are typically used when a system’s performance and integrity are both critical — i.e. your program needs to do exactly what you expect every time and needs to operate in an environment where its tasks can be shared across hundreds or thousands of networked computers. Clojure1, for example, powers Akamai2, the massive content delivery network utilized by companies such as Facebook, while Twitter famously adopted3 Scala4 for its most performance-intensive components, and Haskell5 is used by AT&T for its network security systems.

These languages have a steep learning curve for most front-end web developers; however, many more approachable languages incorporate features of functional programming, most notably Python, both in its core library, with functions like map and reduce (which we’ll talk about in a bit), and with libraries such as Fn.py6, along with JavaScript, again using collection methods, but also with libraries such as Underscore.js7 and Bacon.js8.

Functional programming can be daunting, but remember that it isn’t only for PhDs, data scientists and architecture astronauts. For most of us, the real benefit of adopting a functional style is that our programs can be broken down into smaller, simpler pieces that are both more reliable and easier to understand. If you’re a front-end developer working with data, especially if you’re formatting that data for visualization using D3, Raphael or the like, then functional programming will be an essential weapon in your arsenal.

Finding a consistent definition of functional programming is tough, and most of the literature relies on somewhat foreboding statements like “functions as first-class objects,” and “eliminating side effects.” Just in case that doesn’t bend your brain into knots, at a more theoretical level, functional programming is often explained in terms of lambda calculus9 (some actually argue10 that functional programming is basically math) — but you can relax. From a more pragmatic perspective, a beginner needs to understand only two concepts in order to use it for everyday applications (no calculus required!).

First, data in functional programs should be immutable, which sounds serious but just means that it should never change. At first, this might seem odd (after all, who needs a program that never changes anything?), but in practice, you would simply create new data structures instead of modifying ones that already exist. For example, if you need to manipulate some data in an array, then you’d make a new array with the updated values, rather than revise the original array. Easy!

Secondly, functional programs should be stateless, which basically means they should perform every task as if for the first time, with no knowledge of what may or may not have happened earlier in the program’s execution (you might say that a stateless program is ignorant of the past11). Combined with immutability, this helps us think of each function as if it were operating in a vacuum, blissfully ignorant of anything else in the application besides other functions. In more concrete terms, this means that your functions will operate only on data passed in as arguments and will never rely on outside values to perform their calculations.

Immutability and statelessness are core to functional programming and are important to understand, but don’t worry if they don’t quite make sense yet. You’ll be familiar with these principles by the end of the article, and I promise that the beauty, precision and power of functional programming will turn your applications into bright, shiny, data-chomping rainbows. For now, start with simple functions that return data (or other functions), and then combine those basic building blocks to perform more complex tasks.

For example, let’s say we have an API response:

var data = [
  { 
    name: "Jamestown",
    population: 2047,
    temperatures: [-34, 67, 101, 87]
  },
  {
    name: "Awesome Town",
    population: 3568,
    temperatures: [-3, 4, 9, 12]
  }
  {
    name: "Funky Town",
    population: 1000000,
    temperatures: [75, 75, 75, 75, 75]
  }
];

If we want to use a chart or graphing library to compare the average temperature to population size, we’d need to write some JavaScript that makes a few changes to the data before it’s formatted correctly for our visualization. Our graphing library wants an array of x and y coordinates, like so:

[
  [x, y],
  [x, y]
  …etc
]

Here, x is the average temperature, and y is the population size.

Without functional programming (or without using what’s called an “imperative” style), our program might look like this:

var coords = [],
    totalTemperature = 0,
    averageTemperature = 0;

for (var i=0; i < data.length; i++) {
  totalTemperature = 0;
  
  for (var j=0; j < data[i].temperatures.length; j++) {
    totalTemperature += data[i].temperatures[j];
  }

  averageTemperature = totalTemperature / data[i].temperatures.length;

  coords.push([averageTemperature, data[i].population]);
}

Even in a contrived example, this is already becoming difficult to follow. Let’s see if we can do better.

When programming in a functional style, you’re always looking for simple, repeatable actions that can be abstracted out into a function. We can then build more complex features by calling these functions in sequence (also known as “composing” functions) — more on that in a second. In the meantime, let’s look at the steps we’d take in the process of transforming the initial API response to the structure required by our visualization library. At a basic level, we’ll perform the following actions on our data:

  • add every number in a list,
  • calculate an average,
  • retrieve a single property from a list of objects.

We’ll write a function for each of these three basic actions, then compose our program from those functions. Functional programming can be a little confusing at first, and you’ll probably be tempted to slip into old imperative habits. To avoid that, here are some simple ground rules to ensure that you’re following best practices:

  1. All of your functions must accept at least one argument.
  2. All of your functions must return data or another function.
  3. No loops!

OK, let’s add every number in a list. Remembering the rules, let’s make sure that our function accepts an argument (the array of numbers to add) and returns some data.

function totalForArray(arr) {
  // add everything
  return total;  
}

So far so good. But how are we going to access every item in the list if we don’t loop over it? Say hello to your new friend, recursion! This is a bit tricky, but basically, when you use recursion, you create a function that calls itself unless a specific condition has been met — in which case, a value is returned. Just looking at an example is probably easiest:

// Notice we're accepting two values, the list and the current total
function totalForArray(currentTotal, arr) {
  
  currentTotal += arr[0]; 

  // Note to experienced JavaScript programmers, I'm not using Array.shift on 
  // purpose because we're treating arrays as if they are immutable.
  var remainingList = arr.slice(1);

  // This function calls itself with the remainder of the list, and the 
  // current value of the currentTotal variable
  if(remainingList.length > 0) {
    return totalForArray(currentTotal, remainingList); 
  }
  
  // Unless of course the list is empty, in which case we can just return
  // the currentTotal value.
  else {
    return currentTotal;
  }
}

A word of caution: Recursion will make your programs more readable, and it is essential to programming in a functional style. However, in some languages (including JavaScript), you’ll run into problems when your program makes a large number of recursive calls in a single operation (at the time of writing, “large” is about 10,000 calls in Chrome, 50,000 in Firefox and 11,000 in Node.js12). The details are beyond the scope of this article, but the gist is that, at least until ECMAScript 6 is released13, JavaScript doesn’t support something called “tail recursion14,” which is a more efficient form of recursion. This is an advanced topic and won’t come up very often, but it’s worth knowing.

With that out of the way, remember that we needed to calculate the total temperature from an array of temperatures in order to then calculate the average. Now, instead of looping over each item in the temperatures array, we can simply write this:

var totalTemp = totalForArray(0, temperatures);

If you’re purist, you might say that our totalForArray function could be broken down even further. For example, the task of adding two numbers together will probably come up in other parts of your application and subsequently should really be its own function.

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

Now, our totalForArray function looks like this:

function totalForArray(currentTotal, arr) {
  currentTotal = addNumbers(currentTotal, arr[0]);

  var remainingArr = arr.slice(1);
  
  if(remainingArr.length > 0) {
    return totalForArray(currentTotal, remainingArr);
  }
  else {
    return currentTotal;
  }
}

Excellent! Returning a single value from an array is fairly common in functional programming, so much so that it has a special name, “reduction,” which you’ll more commonly hear as a verb, like when you “reduce an array to a single value.” JavaScript has a special method just for performing this common task. Mozilla Developer Network provides a full explanation15, but for our purposes it’s as simple as this:

// The reduce method takes a function as its first argument, and that function 
// accepts both the current item in the list and the current total result from 
// whatever calculation you're performing.
var totalTemp = temperatures.reduce(function(previousValue, currentValue){
  // After this calculation is returned, the next currentValue will be 
  // previousValue + currentValue, and the next previousValue will be the 
  // next item in the array.
  return previousValue + currentValue;
});

But, hey, since we’ve already defined an addNumber function, we can just use that instead.

var totalTemp = temperatures.reduce(addNumbers);

In fact, because totalling up an array is so cool, let’s put that into its own function so that we can use it again without having to remember all of that confusing stuff about reduction and recursion.

function totalForArray(arr) {
  return arr.reduce(addNumbers);
}

var totalTemp = totalForArray(temperatures);

Ah, now that is some readable code! Just so you know, methods such as reduce are common in most functional programming languages. These helper methods that perform actions on arrays in lieu of looping are often called “higher-order functions.”

Moving right along, the second task we listed was calculating an average. This is pretty easy.

function average(total, count) {
  return total / count;
}

How might we go about getting the average for an entire array?

function averageForArray(arr) {
  return average(totalForArray(arr), arr.length);
}

var averageTemp = averageForArray(temperatures);

Hopefully, you’re starting to see how to combine functions to perform more complex tasks. This is possible because we’re following the rules set out at the beginning of this article — namely, that our functions must always accept arguments and return data. Pretty awesome.

Lastly, we wanted to retrieve a single property from an array of objects. Instead of showing you more examples of recursion, I’ll cut to the chase and clue you in on another built-in JavaScript method: map16. This method is for when you have an array with one structure and need to map it to another structure, like so:

// The map method takes a single argument, the current item in the list. Check
// out the link above for more complete examples.
var allTemperatures = data.map(function(item) {
  return item.temperatures;
});

That’s pretty cool, but pulling a single property from a collection of objects is something you’ll be doing all the time, so let’s make a function just for that.

// Pass in the name of the property that you'd like to retrieve
function getItem(propertyName) {
  // Return a function that retrieves that item, but don't execute the function.
  // We'll leave that up to the method that is taking action on items in our 
  // array.
  return function(item) {
    return item[propertyName];
  }
}

Check it out: We’ve made a function that returns a function! Now we can pass it to the map method like this:

var temperatures = data.map(getItem('temperature'));

In case you like details, the reason we can do this is because, in JavaScript, functions are “first-class objects,” which basically means that you can pass around functions just like any other value. While this is a feature of many programming languages, it’s a requirement of any language that can be used in a functional style. Incidentally, this is also the reason you can do stuff like $('#my-element').on('click', function(e) … ). The second argument in the on method is a function, and when you pass functions as arguments, you’re using them just like you would use values in imperative languages. Pretty neat.

Finally, let’s wrap the call to map in its own function to make things a little more readable.

function pluck(arr, propertyName) {
  return arr.map(getItem(propertyName));
} 

var allTemperatures = pluck(data, 'temperatures');

All right, now we have a toolkit of generic functions that we can use anywhere in our application, even in other projects. We can tally up the items in an array, get the average value of an array, and make new arrays by plucking properties from lists of objects. Last but not least, let’s return to our original problem:

var data = [
  { 
    name: "Jamestown",
    population: 2047,
    temperatures: [-34, 67, 101, 87]
  },
  …
];

We need to transform an array of objects like the one above into an array of x, y pairs, like this:

[
  [75, 1000000],
  …
];

Here, x is the average temperature, and y is the total population. First, let’s isolate the data that we need.

var populations = pluck(data, 'population');
var allTemperatures = pluck(data, 'temperatures');

Now, let’s make an array of averages. Remember that the function we pass to map will be called on each item in the array; so, the returned value of that passed function will be added to a new array, and that new array will ultimately be assigned to our averageTemps variable.

var averageTemps = allTemperatures.map(averageForArray);

So far so good. But now we have two arrays:

// populations
[2047, 3568, 1000000]

// averageTemps
[55.25, 5.5, 75]

Obviously, we want only one array, so let’s write a function to combine them. Our function should make sure that the item at index 0 in the first array is paired with the item at index 0 in the second array, and so on for indexes 1 to n (where n is the total number of items in the array).

function combineArrays(arr1, arr2, finalArr) {
  // Just so we don't have to remember to pass an empty array as the third
  // argument when calling this function, we'll set a default.
  finalArr = finalArr || [];

  // Push the current element in each array into what we'll eventually return
  finalArr.push([arr1[0], arr2[0]]);

  var remainingArr1 = arr1.slice(1),
      remainingArr2 = arr2.slice(1);

  // If both arrays are empty, then we're done
  if(remainingArr1.length === 0 && remainingArr2.length === 0) {
    return finalArr;
  }
  else {
    // Recursion!
    return combineArrays(remainingArr1, remainingArr2, finalArr);
  }
};

var processed = combineArrays(averageTemps, populations);

Or, because one-liners are fun:

var processed = combineArrays(pluck(data, 'temperatures').map(averageForArray), pluck(data, 'population'));

// [
//  [ 55.25, 2047 ],
//  [ 5.5, 3568 ],
//  [ 75, 1000000 ]
// ]

Let’s Get Real

Last but not least, let’s look at one more real-world example, this time adding to our functional toolbelt with Underscore.js17, a JavaScript library that provides a number of great functional programming helpers. We’ll pull data from a platform for conflict and disaster information that I’ve been working on named CrisisNET18, and we’ll use the fantastic D319 library to visualize that data.

The goal is to give people coming to CrisisNET’s home page a quick snapshot of the types of information in the system. To demonstrate this, we could count the number of documents from the API that are assigned to a particular category, like “physical violence” or “armed conflict.” This way, the user can see how much information is available on the topics they find most interesting.

A bubble chart might be a good fit, because they are often used to represent the relative sizes of large groups of people. Fortunately, D3 has a built-in visualization named pack for just this purpose. So, let’s create a graph with pack that shows the number of times that a given category’s name appears in a response from CrisisNET’s API.

Before we go on, note that D3 is a complex library that warrants its own tutorial (or many tutorials, for that matter). Because this article is focused on functional programming, we won’t spend a lot of time on how D3 works. But don’t worry — if you’re not already familiar with the library, you should be able to copy and paste the code snippets specific to D3 and dig into the details another time. Scott Murray’s D3 tutorials20 are a great resource if you’re interested in learning more.

Moving along, let’s first make sure we have a DOM element, so that D3 has some place to put the chart it will generate with our data.

<div id="bubble-graph"></div>

Now, let’s create our chart and add it to the DOM.

// width of chart
var diameter = 960, 
    format = d3.format(",d"),
    // creates an ordinal scale with 20 colors. See D3 docs for hex values
    color = d3.scale.category20c(),

// chart object to which we'll be adding data
var bubble = d3.layout.pack()
  .sort(null)
  .size([diameter, diameter])
  .padding(1.5);

// Add an SVG to the DOM that our pack object will use to draw the 
// visualization.
var svg = d3.select("#bubble-graph").append("svg")
  .attr("width", diameter)
  .attr("height", diameter)
  .attr("class", "bubble");

The pack object takes an array of objects in this format:

{
  children: [
    {
      className: ,
      package: "cluster",
      value: 
    }
  ]
}

CrisisNET’s data API returns information in this format:

{
  data: [
    {
      summary: "Example summary",
      content: "Example content",
      …
      tags: [
        {
          name: "physical-violence",
          confidence: 1
        }
      ]
    }
  ]
}

We see that each document has a tags property, and that property contains an array of items. Each tag item has a name property, which is what we’re after. We need to find each unique tag name in CrisisNET’s API response and count the number of times that tag name appears. Let’s start by isolating the information we need using the pluck function that we created earlier.

var tagArrays = pluck(data, 'tags');

This gives us an array of arrays, like this:

[
  [
    {
      name: "physical-violence",
      confidence: 1
    }
  ],
  [
    {
      name: "conflict",
      confidence: 1
    }
  ]
]

However, what we really want is one array with every tag in it. So, let’s use a handy function from Underscore.js named flatten21. This will take values from any nested arrays and give us an array that is one level deep.

var tags = _.flatten(tagArrays);

Now, our array is a little easier to deal with:

[
  {
    name: "physical-violence",
    confidence: 1
  },
  {
    name: "conflict",
    confidence: 1
  }
]

We can use pluck again to get the thing we really want, which is a simple list of only the tag names.

var tagNames = pluck(tags, 'name');

[
  "physical-violence",
  "conflict"
]

Ah, that’s better.

Now we’re down to the relatively straightforward tasks of counting the number of times each tag name appears in our list and then transforming that list into the structure required by the D3 pack layout that we created earlier. As you’ve probably noticed, arrays are a pretty popular data structure in functional programming — most of the tools are designed with arrays in mind. As a first step, then, we’ll create an array like this:

[
  [ "physical-violence", 10 ],
  [ "conflict", 27 ]
]

Here, each item in the array has the tag name at index 0 and that tag’s total count at index 1. We want only one array for each unique tag name, so let’s start by creating an array in which each tag name appears only once. Fortunately, an Underscore.js method exists just for this purpose.

var tagNamesUnique = _.uniq(tagNames);

Let’s also get rid of any false-y (false, null, "", etc.) values using another handy Underscore.js function.

tagNamesUnique = _.compact(tagNamesUnique);

From here, we can write a function that generates our arrays using another built-in JavaScript collection method, named filter22, that filters an array based on a condition.

function makeArrayCount(keys, arr) {
  
  // for each of the unique tagNames
  return keys.map(function(key) {
    return [
      key,
      // Find all the elements in the full list of tag names that match this key
      // and count the size of the returned array.
      arr.filter(function(item) { return item === key; }).length
    ]
  });

}

We can now easily create the data structure that pack requires by mapping our list of arrays.

var packData = makeArrayCount(tagNamesUnique, tagNames).map(function(tagArray) {
  return {
    className: tagArray[0],
    package: "cluster",
    value: tagArray[1]
  }
});

Finally, we can pass our data to D3 and generate DOM nodes in our SVG, one circle for each unique tag name, sized relative to the total number of times that tag name appeared in CrisisNET’s API response.

function setGraphData(data) {
  var node = svg.selectAll(".node")
    // Here's where we pass our data to the pack object.
    .data(bubble.nodes(data)
    .filter(function(d) { return !d.children; }))
    .enter().append("g")
    .attr("class", "node")
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

  // Append a circle for each tag name.
  node.append("circle")
    .attr("r", function(d) { return d.r; })
    .style("fill", function(d) { return color(d.className); });

  // Add a label to each circle, using the tag name as the label's text
  node.append("text")
    .attr("dy", ".3em")
    .style("text-anchor", "middle")
    .style("font-size", "10px")
    .text(function(d) { return d.className } ); 
}

Putting it all together, here’s the setGraphData and makeArray functions in context, including a call to CrisisNET’s API using jQuery (you’ll need to get an API key23). I’ve also posted a fully working example on GitHub24.

function processData(dataResponse) {
  var tagNames = pluck(_.flatten(pluck(dataResponse.data, 'tags')), 'name');
  var tagNamesUnique = _.uniq(tagNames);

  var packData = makeArrayCount(tagNamesUnique, tagNames).map(function(tagArray) {
    return {
      className: tagArray[0],
      package: "cluster",
      value: tagArray[1]
    }
  });

  return packData;
}

function updateGraph(dataResponse) {
  setGraphData(processData(dataResponse));
}

var apikey = // Get an API key here: http://api.crisis.net
var dataRequest = $.get('http://api.crisis.net/item?limit=100&apikey=' + apikey);

dataRequest.done( updateGraph );

That was a pretty deep dive, so congratulations on sticking with it! As I mentioned, these concepts can be challenging at first, but resist the temptation to hammer out for loops for the rest of your life.

Within a few weeks of using functional programming techniques, you’ll quickly build up a set of simple, reusable functions that will dramatically improve the readability of your applications. Plus, you’ll be able to manipulate data structures significantly more quickly, knocking out what used to be 30 minutes of frustrating debugging in a couple lines of code. Once your data has been formatted correctly, you’ll get to spend more time on the fun part: making the visualization look awesome!

(al, il)

Footnotes

  1. 1 http://clojure.org/
  2. 2 http://www.akamai.com/
  3. 3 http://www.infoq.com/articles/twitter-java-use
  4. 4 http://www.scala-lang.org/
  5. 5 http://www.haskell.org/haskellwiki/Haskell
  6. 6 https://github.com/kachayev/fn.py
  7. 7 http://underscorejs.org/
  8. 8 http://baconjs.github.io/
  9. 9 http://en.wikipedia.org/wiki/Lambda_calculus
  10. 10 http://mathoverflow.net/questions/11916/is-functional-programming-a-branch-of-mathematics
  11. 11 http://programmers.stackexchange.com/a/154523
  12. 12 http://www.2ality.com/2014/04/call-stack-size.html
  13. 13 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tail-position-calls
  14. 14 http://cs.stackexchange.com/a/7814
  15. 15 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
  16. 16 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
  17. 17 http://underscorejs.org/
  18. 18 http://crisis.net
  19. 19 http://d3js.org
  20. 20 http://alignedleft.com/tutorials/d3
  21. 21 http://underscorejs.org/#flatten
  22. 22 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
  23. 23 http://api.crisis.net
  24. 24 https://github.com/gati/lilfunc/blob/master/smashing.html

↑ Back to topShare on Twitter

Jonathon is an entrepreneur and technologist focused on platform architecture, product development, and data science. He currently leads the technology team behind CrisisNET, a platform for global crisis data from Ushahidi. Before CrisisNET Jonathon was CTO of venture-backed travel startup SA Trails, and lead technologist for design/build agency Bright & Shiny. He regularly writes and speaks about data for social good, software architecture and emerging technologies, and tweets @jonathonmorgan.

Advertising
  1. 1

    Thanks for this article Jonathon. I’ve read about functional programming before but this is one of the easiest to follow tutorials.

    7
  2. 2

    A great way to start my morning! Thinking functionally. For me, I’m learning everything is an object (whether it’s HTML, CSS, or JavaScript) and breaking down everything to purposeful responsibilities is gold. Thanks, Jonathon!!!

    6
  3. 3

    You can’t talk about the resurgence of functional programming without mentioning Julia (julialang.org)

    -4
  4. 6

    Anonymous Pedant

    July 2, 2014 5:21 pm

    It should be “a certain cachet” in the first paragraph.

    2
  5. 8

    Nice introduction. Thanks!
    The line
    currentTotal = addNumbers(currentTotal + arr[0]);
    should read
    currentTotal = addNumbers(currentTotal, arr[0]);
    and
    return count / total;
    should be
    return total / count;

    6
  6. 10

    If there will be a pt. 2, you should illustrate how to take those functions and attach them as methods to an object.

    A well structured object with good naming conventions(an emphasis on making the code “humanly readable”) can eliminate the need for any documentation and confusion amongst dev teams.

    It would have also been beneficial for beginners to be introduced to the practice of at-least wrapping functions with an anonymous closure. (function () { ‘use strict’; /*private functions go here*/})();

    3
    • 11

      All good points. I tried to avoid any unnecessary design features here, but you’re absolutely right that, in a production application, wrapping modules in an app scope and using objects (at least as namespaces if you’re not into the whole prototypical inheritance thing) are both good practice.

      3
  7. 12

    One of the best walkthroughs I’ve read in a long-time. Thanks for taking the time to break down the steps into simple chunks. Bonus points for the d3 integration.

    One minor bug, the example after the addNumbers function is introduced, the “currentTotal” and “arr” parameters are swapped:

    function totalForArray(arr, currentTotal) { … }

    Again thanks for the relevant and timely article, looking forward to more deep dives in the future.

    3
  8. 14

    Great tutorial! I couldn’t help but notice that the final code is missing a step:

    tagNamesUnique = _.compact(tagNamesUnique);

    Which actually leads me to a question:

    Does that step not break the ‘rule’ about data immutability. Would it have been more functionally ‘correct’ to refactor to a function like:

    function uniqCleanArray( arr ){
    return _.compact( _.uniq(arr) )
    }

    And then:

    var tagNamesUnique = uniqCleanArray( tagNames );

    2
    • 15

      Yes! Absolutely. I missed that one. I had Array.shift calls all over the place too, then realized that looked bad after making such a big deal about immutability. I really enjoy JavaScript, in spite of its quirks, but mutable lists are a gotcha (at least for me).

      3
  9. 16

    I’m a bit confused, it’s really basic but it’s always better to ask.
    In the example where you introduce recursion (stripping off the comments):

    function totalForArray(currentTotal, arr) {

    currentTotal += arr[0];
    var remainingList = arr.slice(0,-1);
    if(remainingList.length > 0) {
    return totalForArray(currentTotal, remainingList);

    It is my understanding that arr.slice(0,-1); will copy the array excluding the last element.
    then you pass that on to the next call of totalForArray()
    which takes the first element of the array and adds it up to currentTotal

    Shouldn’t we be slicing off the first element of the array instead of the last?
    so that arr[0] is different in every call?

    2
    • 17

      DJ, I’m with you on this.
      given
      var arr = [1, 2, 3, 4, 5];
      then
      var newArr = arr.slice(0, -1)
      >> [1, 2, 3, 4]
      what we actually want is
      var correctArr = arr.slice(1);
      >> [2, 3, 4, 5]

      2
      • 18

        Good catch DJ, and Andrew is correct. It should be arr.slice(1) (the post has been updated to reflect that change) — earlier in the process I thought about iterating “backwards” over the array to demonstrate a different technique then decided against it.

        3
  10. 19

    Nice article, thanks.

    I think you have typo when you called the addnumbers function. When you passes the atguements you separatef them by ‘+’ intead of a comma.

    Thanks again for the great article.

    Dave

    0
  11. 21

    This post made me remember the years I spent learning Pascal, and having it hammered in to me that functional recursion was preferable to for loops.

    I spent 15 years as a functional programmer before being told that OOP was the only way to go. Now we’ve come full circle, back to purely functional.

    5
  12. 22

    As someone who drifted away from programming around the same time that object oriented programming was becoming the norm, I gladly welcome the resurgence of functional programming!

    I knew I’d been avoiding learning OOP properly for a reason!

    4
  13. 23

    Some fallacies here:

    “First, data in functional programs should be immutable”
    In real-time applications, which are still largely programmed in the functional language C, copying data is avoided wherever possible, because of the performance and memory overhead.

    “Secondly, functional programs should be stateless,”
    In real-time applications, implementing functionality without regard to state is impossible. Reacting to an event external to the system’s context always involves awareness of what happened in the recent past.

    “To avoid that, here are some simple ground rules to ensure that you’re following best practices:
    No loops!”
    An unreaslistic restriction.

    -3
    • 24

      All valid remarks. Almost all of the practices mentioned in the article do not apply in any real time application and to most embedded applications. The negative votes are unjustified, the opinions presented in the article under no circumstances can be considered as applicable to the whole domain of functional applications.

      3
  14. 25

    “JavaScript doesn’t support something called “tail recursion,””

    Tail recursion is supported, you just may blow your stack. Any function that calls itself on its last line is tail recursive. A tail call is any function call on the last statement of a function.

    Tail call optimisation is a compiler optimisation that spots tail calls and effectively removes the current stack frame (function) from the stack before calling it – so that tail called function returns to the caller of the current function directly. Its a well-known optimisation that is important for both OO and functional programming, but sadly nowhere near as widely implemented as it should be.

    4
  15. 26

    @Paul.

    I think you’ve confused functional programming (LISP, Haskell, Scheme, …) with procedural or imperative (C, Pascal, etc.).

    Just a language has functions does not make it functional.

    9
  16. 27

    Hey great article! Learning things this way triggers those neurons that make you want “more” :) just a question: I learned some good old Scheme a few years ago and I remember that “higher order functions” are those functions which take a function as an argument or return a function. Also this is the same definition on Wikipedia. But here you say that they are helper functions that allow to avoid looping. Maybe it’s another uncommon definition?

    -1
  17. 28

    I recommend to whoever is interested in functional programming to take this course https://courses.edx.org/courses/LouvainX/Louv1.01x/1T2014/info It is about paradigms and also covers OO and a couple forms of concurrent programming. According to the professor Peter Van Roy it should re-start the next season.

    -1
  18. 29

    Hi Jonathon,

    i’m having a real trouble understanding functional programming. I cannot understand the following code:

    function getItem(propertyName) {
    return function(item) {
    return item[propertyName];
    }
    }
    var temperatures = data.map(getItem(‘temperature’));

    How the “item” parameter is know inside function?
    You are passing one argument to “getItem”, and I understand that the map function passes three more arguments, but still doest make sense to me, because the “item” parameter is the array itself and this is only the third parameter passed by “map”.

    0
    • 30

      Hi Pietro, this snippet is definitely a little tricky. It’s important to understand that getItem returns a function. So…

      var newFunc = getItem(‘someProperty’)

      Now I can call newFunc like any other function – like var someValue = newFunc()

      The function returned by getItem takes one parameter that I’ve called “item”. The “map” array method takes a function as its first argument, and the function passed to map should take a single item from an array as its argument.

      So…

      var arr = [1,2,3]
      arr.map(function(item) { return item + 1 })

      will return a new array – [2,3,4]

      In the snippet, we’re passing the return value of getItem (a function), directly to the map method, which in turn passes each item in the “data” array to that function, one by one.

      Hopefully that helps! If it’s still fuzzy, have a look at the “map” method in more detail. I think that’ll help clear it up.

      1
  19. 31

    Interesting article. Explaining with a concrete example is the best way teach and you do it well here !

    If I may criticize something, as an amateur programmer, it would be the addNumbers(a, b) function. Until used as a parameter of the array.reduce() method, it looks ridiculous. In fact you are telling people to use a function instead of the basic native operator.
    I think it’s a kind of mistake to present people a function like this, even though it is called functional programming. The function gets a real purpose later in the article but I can’t see any advantage of using it instead of the addition operator. I don’t think this should be advised.

    0
  20. 32

    So this is what the rage is about.

    I can see how this improves performance, but at least for me, the readability improvement just isn’t there. Throughout my career, I have had various team leads and colleagues tell me extracting code snippets into methods made the code more “readable”.

    I might be the odd one out on that, but doing the “many small methods” thing just made the code harder for me to read.

    1
  21. 33

    Just a heads up, the first code snippet of data returned from an api is missing a comma between objects. For anyone copying the code to play with they’ll run into an error.

    {
    name: “Awesome Town”,
    population: 3568,
    temperatures: [-3, 4, 9, 12]
    } // COMMA
    {
    name: “Funky Town”,
    population: 1000000,
    temperatures: [75, 75, 75, 75, 75]
    }

    Thanks for the great article!

    0
  22. 34

    You lost me at

    var totalTemp = temperatures.reduce(addNumbers);

    How does calling the function addNumbers work without arguments?

    0
  23. 36

    i.
    it’s not calling but passing function as argument

    var totalTemp = temperatures.reduce(addNumbers);

    is the same as

    var totalTemp = temperatures.reduce(function addNumbers(a, b) { return a + b));

    0
  24. 37

    Great article, and I look forward to functional programming.

    However, using recursive function calls instead of loop seems a bit strange for me. Loops should be more performant than recursion, and (as long as everything happens inside one fonction), does not break immutability anyway.

    Aren’t you using recursion only for the sake of it?

    1
    • 38

      Frankly, yes. These examples are a little contrived. For me using recursive functions or higher-order functions like map, reduce, etc leads to code that makes it clear how data moves through the application, and is subsequently easier to understand at a glance. I find that when I rely too heavily on loops (especially nested loops), it’s hard for me to keep things straight in my head when debugging (ie tough to visualize how data flows and interacts).

      That said, these examples are for the sake of learning the technique. In reality they’re simple enough that recursion isn’t a huge improvement over a loop.

      0
  25. 39

    Very nice tutorial, but I want to express some concern with the repeated warnings about how *difficult* functional programming is. I have practiced OOP for decades, and I am now learning functional JS. Yes, I most certainly do find it quite difficult, but the difficulties come from unlearning patterns and habits of thought. It is hard to teach an old dog new tricks, but I question that this implies that there is inherent complexity in the functional way of thinking.

    Here is a test: If we take people new to programming and teach them the functional approach as their first introduction to programming, would they find it more difficult to learn that OOP?

    I have taught programming to university students for 30 years and witnessed the same concerns regarding OOP. In the mid 1990s, universities switched from Pascal and C to C++ and Java. There was considerably concern over teaching beginners the advanced concepts of objects, inheritance, and (gasp) even polymorphism. However, these concepts are natural metaphors that our students found no more difficult than loops and branches.

    Perhaps our teaching of the functional approach could best be served by a caveat of the form: “WARNING. If you are experienced with OOP, here are some things you need to unlearn: …. (insert words of wisdom here)”.

    Thanks and keep the articles on functional programming coming,
    Kye S. Hedlund
    Dept. of Computer Science
    U. of North Carolina, USA

    0
  26. 40

    Not a single mention of Erlang. Sad. Very sad.

    -2
  27. 41

    Excellent article. I like the way you incrementally develop reusable functions. This illustrates the benefits of the functional approach. However, some programmers may be concerned about the amount of mechanism that appears to be needed to solve the simple problem of average temperature vs. population. An alternate solution is shown below. This fails to meet you didactic goals of teaching functional programming but is offered to address any criticism of “this functional stuff is way too long and involved”.

    Please keep up the good work. More articles on functional programming, please.

    function averageTemperatureVsPopulation( townArray ) {
    return _.map( townArray
    , function( town ) {
    return [ average( town.temperatures )
    , town.population ];
    });
    }
    function average( arr ) {
    var sum = _.reduce( arr
    , function( memo, value ) { return memo += value; }
    , 0 );
    return sum / arr.length;
    }
    // Note that this code does not validate parameters, guard against
    // 0 length arrays, etc. etc.

    0
  28. 42

    I use sublimetext 2 over a year ago. I think its the best text editor until now, and make me fast to develop some themes on http://masandik.com until now.

    -5
  29. 43

    What about the overall complexity of the algorithm where array of x,y is created. Multiple passes was done on the same array and at the end they were combined. Any thoughts?

    0
  30. 44

    sir i am face daily complexity in programming. whenever i seen programs than i get so confused. i think functional programs are very complex then other programs. is there any trick to learn it easily.

    0
  31. 45

    This is a great introduction to FP.

    I’d like to suggest that although libraries like Underscore and LoDash can be very helpful in building your applications, there is a lot to be said for the new breed of functional libraries such as Wu, Fn, Lazy, Lz, or the one I’ve been working on Ramda, which is designed to let you build such applications through simple functional composition.

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top