JavaScript closures for Java programmers

I switched recently from back-end programming in Java to front-end programming in JavaScript and even if I know that these two languages are different it is hard for me to not compare them. I believe that if I will be able to correlate similar paradigms, I will understand better both languages and I will be a better programmer.

One of the paradigms heavily used in JavaScript is closure. In my terms a closure is a function that remembers and uses its environment. I will not get into details about when closures are useful, you can find more about them in mozzila developer network. In this post I will cover a concrete example in both JavaScript and Java with the main difference I found between them.

In my example I want to apply a discount for sold goods based on goods type.

Function calculator receives goodsType as parameter, it computes the discount for that type of goods and returns a function that will apply it every time without being needed to compute it again. How this example will look in Java? The first and naive 1:1 version looks like:

It is almost the same but it doesn’t work because it fails to compile with:

The problem is that we are not allowed to change a variable used in a lambda expression and in our case it is the discount variable. This was the reason I decided to write this post because when I learned how to write closures in JavaScript I remembered about this situation. The fix is to change discount variable to be final or effectively final.

In this case it is effectively final because it is computed in the new getDiscount method, it is created and assigned only once in calculator method and not changed anymore after that.

The fact that I’m allowed to use a variable that changes its value in JavaScript closures, it means that I can go even further with my example. If I want to change the discount based on how much I sell, I can do this:

I change the future discount during the current sell, so that the price of the next sell will be even better.

Thank you for reading this post and I hope that you found it useful.