Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why - in Java 1.8 - is Function<V,R> used and not Function<R,V>?

The order seems odd because in regular Java the return type is always specified first. As in:

public static double sum(Iterable<Number> nums) { ... }

Why then, in the Function and BiFunction classes has the choice been made to specify them the other way around? As in:

interface Function<T,R>
interface BiFunction<T,U,R>

I'm not asking here for opinions as to which is better, but specifically:

a) Is there any technical or other (non-stylistic) benefit in preferring one order over the other? Or is it an arbitrary choice?

b) Is anyone aware of any documented explanation, or any stated reason from an authoritative source, why one was chosen over the other?

Aside: the order seems even more odd if extended to higher arities. For example, a hypothetical QuadFunction:

interface QuadFunction<A,B,C,D,R> { ... }

(At the time of writing the highest arity in the library is 2 - i.e. BiFunction.)

See: http://download.java.net/jdk8/docs/api/java/util/function/package-summary.html

like image 347
Paul Avatar asked Nov 01 '13 12:11

Paul


4 Answers

It is to be consistent with prior existing notation.

The mathematical integer division function extended into the rational numbers:

(\): I x I -> Q

Functional programming version of the above (like Haskell, Ocaml)

division :: Integer -> (Integer -> Rational)

or

division :: Integer -> Integer -> Rational

All three say "the division function takes two integers and returns a rational number". It is backwards, in a functional paradigm, to say your returns first. C has taught us to say "we return a rational number in the division function, which takes two integers" (ex float division(int a, int b){}).

In Java, your return type is on the left of methods because Java wants to look like C. The designers of C thought "int main(int argv, char *argv[])" looked better than "main(int argv, char *argv[]) int". When writing code, atleast for me, I more often than not know what a method will return before I know what it will need. (edit 1: and we write lines like String s=removeSpaces(textLine), so the return on the left matches the variable on the left)

In C#, func looks the same way as the Java 8 Function.

like image 58
Lan Avatar answered Nov 15 '22 08:11

Lan


My guess is that it's more intuitive for method chaining which might be a typical use case for lambdas, i.e.

IntStream.range(1, 10).map(Ints::random).filter(x -> x % 2 == 0)

So, method sequense here reads left to right and lambdas go left to right. So why not having the type params go left to right?

Escalating this a bit further - the reason might be that the English language reads left to right. :-)

UPDATE

I was very surprised to find out that this is something which takes place for maths modern arabic notation:

Latin complex numbers

latin complex numbers

Arabic complex numbers

arabic complex numbers

In this example arabic notation in every char mirrors latin. One can track this by the angle sign and i (imagenary unit) char - in both cases it has a dot. In the linked wiki article there is also an example of a reversed lim arrow (compared to Java 8 lamda's arrow direction). This could mean that arabic Java, if it was ever developed, would look a bit differently. :-)

Disclaimer: I have background in maths, but I had no idea of the arabic notation when I was answering this question.

like image 37
Andrey Chaschev Avatar answered Nov 15 '22 06:11

Andrey Chaschev


In ordinary procedural and OO programming, functions/methods generally take a list of parameters and return some result:

int max(int num1, int num2)

When rewriting function signatures as callback-based (such as for parallel or asynchronous processing), it has been a longstanding practice to convert the signature by appending the return callback as the last parameter:

void maxAsync(int num1, int num2, Callback<int> callback) // pseudo-Java

A current example of this pattern can be found in GWT RPC processing.

This style originated in the Lisp style of languages with the so-called continuation-passing style, where functions are chained by passing a function to a function as a parameter. Since in Lisp arguments are evaluated left-to-right, the function that's consuming the values needs to be at the end of the list. This arrangement has been adopted by imperative languages for continuity and because it's been traditional to tack on additional optional parameters (boolean flags and the like) at the end of the parameter list.

like image 24
chrylis -cautiouslyoptimistic- Avatar answered Nov 15 '22 07:11

chrylis -cautiouslyoptimistic-


It is the explicit intent to make it more convenient to program in a functional style in Java. Now, in mathematics, a function is generally written like

f: A -> B

(i.e., a function from As to Bs). This corresponds also to the notation in functional languages, Scala and already existing functional libraries for Java.

In other words: it is just the right thing.

Note that a functional interface is not a method and a method is not a functional interface, hence it is not clear what the syntax of the former has to do with the latter.

like image 36
Ingo Avatar answered Nov 15 '22 07:11

Ingo