What is Java Currying?

Learn via video course
FREE
View all courses
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Topics Covered

Since Java 8, we have been able to define 1- and 2-parameter functions in Java, allowing us to pass their parameters as inputs to other functions to modify their behaviour. Java Currying is used for functions with more parameters, though. Currying and functional interfaces can be combined to design simple builders that require all inputs from the user.

To break a function with many arguments into many functions with a single argument such that the output is the same is function currying.

Consider it the same as making ratatouille; you can't just make it with one ingredient; you need more!

Java Currying is a method used in mathematics and computer science to split up a function that accepts multiple parameters into a series of functions that only accept one argument each.

In essence, it means that we can break a function into a succession of mini-functions that each takes a single argument until we return all of the parameters.

FUNCTION

Let's look at an example in Java:

The method multiplynum in the previous section returns the multiplication of three numbers.

The identical line of code mentioned above can be expressed as a lambda expression in the following way:

Let's dissect the code sample above so that we can comprehend it so it doesn't look as complicated as it does right now.

Curry() has the following return type:

  • Line 2 has a method that accepts an Integer.
  • At line 3, this function returns a different function that once more returns an Integer.
  • At line 4, this function then returns a different function. Two parameters are passed to the function at line 4: the first is the type of parameter it accepts (an Integer), and the second is the type of result we will receive after performing the entire process (an Integer)

In the main method, we would have something like this:

Here in the above example, you can see we've used two different methods here to help readers understand the distinction between the ordinary and curried method. In the ordinary method we've used here, we just call a function multiplyNumber(), which takes three arguments for the sake of obtaining the result, which is printed right after

In the curried method, however, it returns a function that accepts the first number and returns a function that accepts the second number, which again returns a function that accepts a third number and returns a number and finally prints out the result .

Syntax

Let there be a function that maps as f:(u, v) -> w

Currying the above function will produce g:(u->(v->w))

Thus g maps from u to a function, which in turn maps from v to w

The above mathematical expression can also be represented as: {g(u)}(v)=f(u, v)

Hence, curry(f) = g

Simple Examples

Let's look at a real-world illustration of a letter with several parameters in Java

We create a class Letter with a Salutation and body defined in it; the constructor of the same class then initializes the object; we expand upon this code further in other sections.

2.1. Creation by Method

here in this code,

A new object is created of type Letter with the content as salutation and body passed to it.

2.2. Creation with a function

We can use function for this from Java 8 now.

While the code previous to this one works well as well, for instances where we need to add this behaviour to a functionally-written piece of writing, we can use the function in Java

2.3. Creation with a Sequence of Functions

This can be rephrased as a series of functions, each having a single parameter, let's see how to do it in Java:

We can observe how a salutation corresponds to a purpose. The resulting function maps into the new Letter object. See how BiFunction's return type has been modified. Only the Function class is being used. Java Currying is converting a set of functions into one another.

Advanced Examples

Let's add more parameters to the constructor of our Letter class to demonstrate the benefits of Java Currying. Let's see its implementation in Java.

Just like before we've defined a Letter class with returning address,inside address; LocalDate date of letter, salutation, body, and closing, which are then also passed onto constructor for initialization.

3.1. Creation by Method

Java:

Here observe,

A new object is created of type Letter with the content as returnAddress, inside address, date of letter, salutation passed to it.

3.2. Functions for Arbitrary Arity

Arity is a metric for how many parameters a function accepts. There are only three functional interfaces for binary (BiFunction), unary (Supplier), and nullary (Function) in Java. We are unable to offer a function with six input parameters without first establishing a new functional interface.

Consequently, we obtain:

Java Currying is the solution. It converts a variety of arities into a run of unary functions, as you can clearly see in the program above.

3.3. Verbose Type

It is clear that the type above is not entirely readable. We use the word "apply" six times in this fashion to make a letter:

Here, a function that accepts RETURNING_ADDRESS returns a function that takes CLOSING as its argument and returns another function that takes DATE_OF_LETTER which then in turn returns INSIDE_ADDRESS which returns another function that takes SALUTATION which finally calls another function which then takes the body as it's an argument

3.4. Pre-Filling Values

With the aid of this series of functions, we can build a helper that pre-fills the initial values and returns the function needed to finish the letter object:

Be aware that in order for this to be beneficial, the order of the parameters in the original function must be carefully considered so that the parameters with the lowest specificity come first.

Builder Pattern

We can utilize the builder pattern to get around the hostile type definition and the repeated use of the standard apply method, which leaves you with no idea of the correct order of inputs:

We employ a series of functional interfaces as opposed to a series of functions. Keep in mind that AddReturnAddress is the returning type used in the definition above. We only need to define the intermediary interfaces in the following:

So, using this to create a Letter is quite self-explanatory:

Notice that the interfaces ensure the filling order. So, we can't just pre-fill closing.

The 3 Stages of Java Currying

Take a moment to apply what we've learned about java currying implementations in general.

The initial, middle, and final steps are present in any currying implementation.

The initial step is the first time the curry method is called. In it, invokers relay to us the identity of the curry caller. For methods, it is null, while, for instance, for methods, it is obj. The final phases represent the actual invocation of the curried function, whereas the intermediate stages include gathering all the parameters required for the curried function. Typically, the invocation is made, and the parameter is captured in the last step. Curry would be used in place of the invocation for curry else. Curry will resemble apply(1), apply(2), and apply(n). We cannot have apply(1).apply(2).apply(n).accept()!

With that, we’re ready for…

Examples

Example 1 : Currying Function to Concatenate the Strings

In this illustration, we'll use the curried function to concatenate two Strings using two string inputs. We'll combine the apply method and the curried function to combine the strings.

Output

Here in the above Java program right after curried function is called for the purpose of concatenating the strings in verbose type, the said curried function takes two strings as it's argument and then concatenates the strings

Example 2: Currying Function to Evaluate the Expression

Let's see how we can evaluate an expression using the java currying function

Output

We build a curried function that takes three integer parameters. To pass those three arguments, we use the apply method, and an outcome is finally determined.

Learn More

Learn more about methods in java here

Conclusion

  1. Java Currying is a method used in mathematics and computer science to split up a function that accepts multiple parameters into a series of functions that only accept one argument each
  2. Arity is a metric for how many parameters a function accepts. There are only three functional interfaces for binary (BiFunction), unary (Supplier), and nullary (Function) in Java
  3. Currying and functional interfaces can be combined to design simple builders that require all inputs from the user