Multi-ary functions in Java

Let me remind you: arity is the number of function parameters. Correspondingly multi-ary (this word can be written together or separately) functions are functions with several parameters. In Java 8, functions with one and two input parameters were introduced. But what if there are more parameters?
When you need a lot of input parameters
Function exists in Java
Where does such injustice come from? Why is it possible to define a method with any number of parameters in a class, and functions with three or more parameters need to be defined specifically?
But if necessary, we will try to determine. But how? Surely you heard about currying - a method of converting a function with N parameters into a function with N - 1 parameters. And probably this is the first thing that many people will immediately think of: I need to curry my multi-parameter (multi-parameter) function! But here is how to convert your specific function?
For example, you have a function
You already guessed how to bring it to mind
I will not torment you further. Do not be alarmed. Java 8 does it for you. For example, to further define functions with three input parameters:
@FunctionalInterface
public interface Function3Arity {
R apply(A a, B b, C c);
}
After that, you can define specific varieties of ternary (three-ary) functions. For example, like this:
private static Function3Arity f3 =
(a, op, b) ->{return "" + a + op + b + "=" + (a+b);}; Check out how it works:
@Test
public void testFunction3Arity() {
String result = f3.apply(2, "+", 3);
assertEquals("2+3=5", result);
}
You must define the appropriate interfaces for each arity used N = 3.4, ...
And everything would be fine, but the only bad thing is that it is simply impossible to come to this decision in a rational way. (If you, like me, are not an expert in the field of functional programming). I mean the ability of the apply method to perceive and correctly interpret an arbitrary number of parameters. This is not written in the documentation. And it is not written whether this can be done in any other way. And when I faced this problem, I was hoping to find something similar in the specification of the Function class or the package containing it. For example here or here .
When you need a lot of output parameters
We looked at an example where there were many input parameters. But what if we have a lot of output parameters?
As you know, Java allows return to return only one primitive element or object. But I would like to be able to distinguish between input and output parameters already at the level of the function signature. Those. have signatures like:
From my point of view, using is more elegant
For example, the Tuple2 class looks like this:
public class Tuple2 {
public final A a1;
public final B a2;
public Tuple2(A t, B u) {
a1 = Objects.requireNonNull(t);
a2 = Objects.requireNonNull(u);
}
@Override
public boolean equals(Object o) {…}
@Override
public int hashCode() {…}
}Using this class, a function with three input and two output parameters can be defined like this:
private static Function3Arity> f3And2 =
(a, op, b) ->{
int intValue = a + b;
String sValue = "" + a + op + b + "=" + (a+b);
return new Tuple2<>(intValue, sValue);
};
Let's check how it works:
@Test
public void testFunction3And2Arity() {
Tuple2 result = f3And2.apply(2, "+", 3);
assertEquals(5, result.a1);
assertEquals("2+3=5", result.a2);
}Final rule
- If your function has 3 or more input parameters (s), you need to define a new N-ary interface and use it to subsequently define specific functions.
- If your function has 2 or more output parameter (s), define the TupleN class and pack parameters into it before output from the function using return.
You can find code examples in my GitHub project here .
Illustration: geralt