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

in #blog7 years ago

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 like 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 I'm doing at Amazon.

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)).

So What?


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. And, not only that, we can pass the predicate to be evaluated in the if statement as a parameter as well, in case the customer decides they want to check for prime numbers instead of odd ones.

Another possibility: 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.

Conclusion


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.

Sort:  

I dislike Java a great deal these days. It causes more problems than it used to solve. Oracle really dropped the ball when it took over. Many things that once worked are now broken. The language as a LEARNING tool is still useful, but there are other object oriented languages so other than LEARNING I don't see java as particularly useful in an actually applied fashion.

I first started learning Java before the first VM that could run it was completed and out of alpha.... I saw some bizarre things. Then it got good for awhile and dominated. Then oracle acquired it, and it has been consistently downhill since then.

my friend of the king :D keep going like this :D

I'm not sure I follow, but thanks for reading!

When I grow up I want to be just like you. Genius.

Hey @five34a4b

I am completely new to Functional Programming, thus this post gave me some clarity.

Since you are into Programming, would you mind sharing your Opinion about this post.
https://steemit.com/art/@premraval010/the-art-of-computer-programming-or-donald-knuth

Great post! I love have you tagged it under art. I feel programming really is an art and a craft that's perfected over a lifetime. I just finished "Clean Code", highly recommend it if you haven't read it already.

Oh Yeah, I will surely read it.
Would you mind sharing the link to it.

Great info...resteem..

awesome! thank you for the resteem!

Keep going to your very informative post my friend @five34a4b

Good informations

Thanks for reading!

Yes true to your words.

Thanks for reading!

Informative post

Thanks for reading!

Coin Marketplace

STEEM 0.18
TRX 0.15
JST 0.029
BTC 62837.64
ETH 2542.11
USDT 1.00
SBD 2.65