Use Lambda Functions to understand Functional Programming

Use Lambda Functions to understand Functional Programming

About this Series
In this article, you will learn the basic philosophy behind functional programming.

However, there are different ways of looking at it. Each article in this series will explain it differently and will use a different programming language to do so.

Series overview:

  • Pure Functions in JavaScript

  • Pipelines in Phyton

  • Lambda Functions in Java

Today we will use Java to discuss

Lambda Functions.

In Functional programming, a function is just data.

The name Lambda Function comes from the mathematical theory called Lambda Calculus and describes this way of considering functions as the fundamental building block of programs.

//Normal Function
public int add1 (int number1,int number2) {
  return number1 + number2;
}

//Lambda Function
public BiFunction<int,int,int> add2 = 
  (number1,number2) -> number1 + number2;

add1(1,2);
// 3
add2.apply(1,2);
// 3

Here we have a function add1 that adds two numbers. But we can also define a variable add2 as a function doing the same thing. Now the magical thing is, that we can pass this variable on to another function.

public reduce(BiFunction<int,int,int> func,int[] arr){
  int output = 0;
  for (int element : arr) {
    output = func.apply(output,element);
  }
  return output;
}

reduce(add,array(1,2,3,4,5))
//1+2+3+4+5

In this example we define a function reduce that takes an array and a way of combining elements of the array (in our case adding them). It then iterates over the array and applied that function, returning the result.

You might have seen something similar with functions like map or filter. So if you have used these functions already, then you could call yourself a functional programmer. Functional Programming and Lambda Functions are so common nowadays, that you start using them without realizing it.

Benefits

The ability to store and pass functions around at will is very useful. In Object Oriented programming this is sometimes called the Strategy Pattern.

So this isn't a new concept. What is new however is how easy it is to apply this pattern.

If you are interested in reading more about functional programming, in particular in Java, then I can recommend you Functional Programming in Java by Pierre-Yves Saumont. Feel free to also subscribe. Follow me on my journey explaining functional programming from different angles and using different programming languages.


Advanced: Currying

You might have noticed, that we only passed the variable as an argument, but we didn't show how we use a lambda function as a return value.

Ok then, if you still got time, let's rewrite the first example a bit:

Function<int,Function<int,int> add = 
  (number1) ->
    (number2) -> 
      number1 + number2;
  }
}

Function<int,int> addOne = add.apply(1)
echo addOne.apply(2)
//3
echo add.apply(1).apply(2)
//3

We now pass each argument one at a time. This way we can easily create a new function (addOne) that always adds one. We can even pass the function to a map and apply it to all values of a list.

map(add.apply(41),array(1,1,1))

This trick is called partial evaluation and a function that takes one argument at a time is called a curried function (named after the inventor Haskell Curry).


Come to think of it, is it possible to create a lambda function that has infinitely many arguments? I'd like to read your answer in the comments.