Functional Programming in Java

in #programming7 years ago

As I stated in my previous post I'm deep diving into Java because that's the primary language used at Amazon. The first thing I did was investigate what functional aspects have been added to the language since I last used it, because I enjoy the functional nature of JavaScript. In this tutorial, I'll show you what I've learned so far.

Our Previous Example


To begin, let's rewrite the Java example used in the previous post in order to show how Java has evolved to handle functions with Java 8. Originally we had:

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));
}

This can be rewritten functionally as:

public static Function<Integer,Integer> addOne = (Integer number) -> {
    return number + 1;
};

public static Function<Integer,Integer> squareNumber = (Integer number) -> {
    return number*number;
};

public static Integer composeFunctions(Function f1, Function f2, Integer input){
    return (Integer)f2.apply(f1.apply(input));
}

You'll notice a few peculiarities that don't match up with the JavaScript example. The first is the lambda functions. In the case of our JavaScript example, we were able to assign our functions to variables:

var fun = function(){
    console.log("I'm a function!");
}

(anyone? anyone? alright...sorry back to the code....)

However, we can use a slick bit of syntax named the "fat-arrow function" to write this another way:

var fun =  () => {
    console.log("I'm a Star Wars");
}

That's all this is in the Java code, but they're called "lambda functions" and they use -> instead of =>. Obviously there are going to be some differences in the details, but for our purposes, you can view them as the same. (note, they're also called anonymous functions)

A second peculiarity you'll notice is the Function<Integer,Integer> variable type. This is Java's way of overcoming the "functions can't be variables" we talked about in the previous post. This variable is a Function variable (just like Integer, or String). The syntax is a throwback to the OG functional programming languages as they define their functions similarly. What it's saying is "this is a function that receives an Integer type and returns an Integer type".

This allows Java to do things like have functions which take Integers and return functions that take Integers and return Integers (Function<Integer,Function<Integer,Integer>>), or functions that take functions and return functions that take Integers and return Integers (Function<Function<Integer,Integer>,Integer>> I could go on for days, here simultaneously having a bit of fun, as well as foreshadowing for my frustrations with the Java language below).

Yet another peculiarity is this .apply() business. JavaScript has this as well, and honestly I haven't looked into the difference between .apply() and simply calling the function in JavaScript, although I'm certain there is a difference. But anyway, that's all that's happening here. f1.apply(input) is calling our first function with the input, this is returning an Integer, which is passed into f1.apply(), thus calling f1, and, finally, we return the result when the f1.apply() call finishes.

The final peculiarity is, the .apply() method returns an object. We need to cast this object to an Integer which should be safe enough given we can see the function we're passing in returns an Integer, however, it would pay to be extra safe about this if you were writing any kind of serious code, especially because the parameter is simply a Function, and not a Function<Integer,Integer> specifically.

In the previous post I pointed out that JavaScript is a mess of a language. Here we see one of the differences between JavaScript and Java, and that's static typing (I've heard this joked about as "JavaScript: everything is everything!"). Here we are explicitly defining that the first two parameters passed into our composeFunctions method must be functions (ok, I'll admit, bad naming). In the case of the equivalent JavaScript code, we could very easily pass in an object in place of the function and we won't get an error until run time, this can lead to some nasty bugs, and a severe lack of readability when looking at other people's code. But I digress, onto the next example!

First Class Functions In Java

public static void testFunction(String name){

    Runnable innerFunction = () -> {
        System.out.printf("hello! ");
    };

    BiConsumer<Runnable, String> lateExecution = (Runnable inputFunction, String n) -> {
        inputFunction.run();
        System.out.println(name);
    };

    BiConsumer<Runnable, String> lateNoExecution = (Runnable inputFunction, String n) -> {
        System.out.println(name);
    };

    lateExecution.accept(innerFunction, name);

    lateNoExecution.accept(innerFunction,name);

}

We previously discussed the issues with JavaScript, so now let's bitch about Java. In the equivalent JavaScript code from the previous post it was extremely succinct and easy to follow what was going on. We were defining some inner functions, assigning them to variables and calling them. The code is literally running off the page in this Java example. In this Java case, you have to know what a Runnable is, and that it's an functional interface (whatever that is) that takes no parameters and returns none. You also need to know that a BiConsumer takes two parameters specifically, and returns nothing. Don't you dare try using the Function interface for either of these things. Don't think about calling apply() on the BiConsumer either.

The equivalent JavaScript took me 1 minute to write and didn't involve any googling or a compiler to double check. Sadly, I can't say the same for the Java. Obviously the functional aspects of Java were an afterthought (which is fine, it wasn't intended for that purpose anyway), and you get that feeling when trying to program functionally in it.

Remember in the previous post when I asserted that functional languages are great because the modularity is natural to a programmer, making it more probable to occur? When you have to memorize 10 different functional interfaces to get anything done, that reduction in cognitive load vanishes.

In the next post I'm thinking we'll look further into lambda functions, as well as the .map(), .filter(), and .reduce() higher order functions (used in the famous Hadoop big data framework). Until then!

Sort:  

Resteemed by @resteembot! Good Luck!
Curious? Read @resteembot's introduction post
Check out the great posts I already resteemed.

RESTEEMBOT IS FOR SALE
I COULD WRITE CODE FOR YOU

This post has received a 4.58 % upvote from @booster thanks to: @five34a4b.

I'm a former software engineer ( Java was also my primary language ) and I've got a question for all you other programmers. Have you ever gotten burnt out from programming?

I certainly know I did and I don't know if I'll ever be able to do that full time ever again despite the fact that it's a high paying job.

I sometimes do, I often find I need to take a step back and remind myself that I enjoy programming from an artistic perspective and focus on that any time I start to feel burnt out. I also remind myself that finding good developers isn't non trivial, and that helps relieve the stress some times.

Your bio says you're now an entrepreneur. I'd like to move into that space as well eventually. I mean, given the choice between entrepreneurship and software engineer I think I'd prefer entrepreneurship.

Great read,

I am just starting out in Java & its only my second week into it.
It is really great when i see posts like this as it is really helpful.

Great work.

Thanks.

Thanks for reading! is there a particular reason you chose Java?

No problem,

I have chosen Java as i believe that is the most commonly used , I am also working on Java script, J -query, HTML5 & CSS 3.

What languages have you learned ?

I have chosen Java as i believe that is the most commonly used

I'd say its the most common in large tech companies but not start ups.

What languages have you learned ?

I can program relatively well in R, JavaScript, Java, C++, Python, and SQL. I'm passingly familiar with Solidity.

I love R. I played around a bit in Julia too, it's like R but you have the option of strong typing. Great efficiency gains.

Hmm, interesting, never tried Julia, didn't know that!

very interesting post! I am also fond of IT. Hopefully, One day I can understand something about it same as you!

Coin Marketplace

STEEM 0.19
TRX 0.15
JST 0.029
BTC 63184.34
ETH 2560.17
USDT 1.00
SBD 2.72