The Power of Functional Programming (and why we’ll be exploring it in Java)

I dislike Java as a programming language.

I learned C++ at Utah State University (not that I like C++ any better), we were required to take a Java course to supplement the C++ knowledge, but I had studied Java in my free time before going back to school anyway.  I am grateful to Java as it was my first experience with Object Oriented Programming (OOP).  C++ is less verbose than Java, but I don’t necessarily love C++ more than Java.  In all honesty, I’m not much of a language snob.  I’m firmly in the “choose the language that’s best for the job” camp.  Which is why I haven’t complained about using Java.  It really is the right tool for what Amazon is doing.

This is why after school I focused heavily on learning JavaScript.  In my opinion JavaScript is an absolute mess of a language, however, in many cases, particularly the projects I’m interested in building, it is the best tool for the job.  One thing in particular I like about programming in JavaScript is it’s functional aspects.  I’m not one for details or pedantry, so I’ll stay out of defining functional programming or using any programming language buzz words.  Here is the wikipedia to Functional Programming though, and if there is interest, I’d be more than happy to dive into other details of functional programming not discussed here (we’ll only be covering a very small subset).  For now, I’ll take a very simple definition of functional programming: functions can be treated as variables in functional languages, as this is the most advantageous aspect the paradigm possesses over procedural languages (C++, Java, etc).

I remember when I first heard of functional programming.  I thought “great, so what? I can accomplish anything I need to in a procedural language, why bother learning another paradigm and confusing myself?”.  In fact, although I’d dabbled in Haskell, this was more out of curiosity about all the hype surrounding functional programming than anything else.  It was really certain frameworks in JavaScript (looking at you React.js) that naturally lend themselves to the functional paradigm that introduced me in a pragmatic way.

Higher Order Functions

So functions can be treated as variables, what does this really mean?  Here’s a contrived example to illustrate the point:


var addOne = function(number){
    return number + 1;
};

var squareNumber = function(number){
    return number * number;
}

var composeFunctions = function(func1, func2, input){
    return func2(func1(input));
};

Calling composeFunctions(squareNumber, addOne, 100) will square 100, pass the result into addOne, and add 1 to 10000.  Here’s the equivalent Java code:


public static Integer addOne(Integer number){
    return number + 1;
}

public static Integer squareNumber(Integer number){
    return number*number;
}

public static Integer composeFunctions(Integer input){
    return addOne(squareNumber(input));
}

If you’ve studied functional programming in any small sense, you’ll be able to spot a limitation with this Java code (hint: notice how in the JavaScript we’ve got three function parameters to composeFunctions, but only 1 in the Java code).  What happens if we want the ability to call the addOne function first, and then the squareNumber function after that?  We’d have to add a second Java method for this and explicitly call these functions in the reverse order:


public static Integer composeFunctionsReverse(Integer input){
    return squareNumber(addOne(input));
}

This is because in the past, Java couldn’t treat functions as variables, and because of this, you can’t pass a function into another function as a parameter.  In the case of the JavaScript, if we wanted to change the order the functions executed in, it’s as simple as swapping the parameters to the function (calling composeFunctions(addOne, squareNumber, 100) instead of composeFunctions(squareNumber, addOne, 100)).

I remember when I was looking into functional programming initially, I saw examples like this and thought “great, so what? I’ll just write another one line function, what’s the big deal?”.  I’ll admit, in this contrived example it doesn’t seem like much.  However, when you start adding things like networking code to make API calls, or threading, the power of this small abstraction becomes enormous.  Not to mention the cleanliness of the code (we didn’t have to write the second function in the JavaScript case).

First Class Functions

Another powerful aspect of this paradigm is, the functions can be written inside of other functions, and executed whenever the programmer dictates:


var testFunction = function(name){
    var innerFunction = function(){
        //ignore the process.stdout.write, it's just console.log
        //without the newline
        process.stdout.write("hello! ");
    };

    var lateExecution = function(inputFunction, name){
        inputFunction() + console.log(name);
    }

    var lateNoExecution = function(inputFunction, name){
        inputFunction + console.log(name);
    }

    lateExecution(innerFunction, name);
    lateNoExecution(innerFunction, name);
}

Here is yet another contrived example, however, it illustrates the point quite well, particularly because there is no equivalent Java code to do the same thing (until recently of course, check out the next tutorial for this).

When we call testFunction(“Jackson”), the innerFunction is created at the time of calling, we then pass this variable into both our lateExecution and lateNoExecution variables (also both created at the time of calling testFunction).  The lateExecution function receives this innerFunction, immediately calls it, then console.log’s the name passed into it.  However, in lateNoExecution, we don’t ever execute the function passed to us, so nothing happens, other than “Jackson” is printed to the screen, even though we still have access to the function as a variable.

I know if you’ve come from procedural programming, you’ll read the above paragraph and thinking “man, that’s a lot of this calling that, calling this, but maybe not calling that, and only when the function is executed”.  I know because I thought the same thing.  But now that I’m on the other side of the fence I’m realizing the writers of posts I’d read previously were simply struggling to come up with succinct examples motivating the paradigm.  It just isn’t easy to motivate functional programming in small examples.  The paradigm really shines when code starts to grow very large, because functions can be chosen or removed at will and modularized with one simple key stroke rather than redesigning the software from the ground up (looking at you class hierarchy diagrams).

As an example, in the composeFunctions portion of this post, what would happen if we needed to do some preprocessing on the number passed into us before calling the other two functions, based on whether the number was even or odd?  We’d do the check on the number, and add the preprocessing.  Well next month, a customer has decided the preprocessing needs to be done in another way.  Between now and then, we’ve added a bit more logic in that if statement block.  Now we need to unravel the entire mess and change whatever preprocessing we were doing, which may effect logic (aka mutate state) later in the scope without us noticing.  If we were using functional programming, we’d have simply added a third preprocessing function as a parameter to composeFunctions, and called it inside the if statement.  When the customer changes the preprocessing requirements, we simply pass in the new function.

Another possbility: what if we wanted to reuse this composeFunctions method for a succession of two different function calls, rather than squareNumber and addOne?  (perhaps cubeNumber and addTwo?) without removing the functionality gained from the original code?  In Java you’d have to write a new function, calling cubeNumber and addTwo specifically, whereas here, we need only call composeFunctions with the newly written cubeNumber and addTwo (or hell, even cubeNumber and addOne, or addOne and addTwo).

This paradigm lends itself to modularity in a way procedural programming does not.  I’m not saying you couldn’t accomplish the same things in a procedural language, but what I am saying is, it’s much easier to do in a functional language, making a programmer much more apt to reach for it.

Hopefully I’ve managed to motivated the power of functional programming (although after reading the above paragraphs, I’m not sure sure I have! ha ha!).  This is a very small piece of the larger paradigm, and in fact, the power isn’t done justice by these contrived examples, the power lies in the completely new way of looking at code, rather than specific use cases or academic ammunition for water cooler arguments over which language is better.  As we’ll see in the tutorial, even traditionally procedural languages are adding functional aspects because of it’s power.

One thought on “The Power of Functional Programming (and why we’ll be exploring it in Java)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s