What is the "functional form" in relation to functional interfaces in Java 8?

In Java 8, the new java.util.function package contains many functional interfaces. The documentation for this package ( http://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html ) contains several links to "function shapes":

  • There are several basic forms of functions , including a function (unary function from T to R), consumer (unary function from T to void), Predicate (unary function from T to logical), and provider (zero-function for R).
  • Forms of functions have a natural essence based on how they are most often used. Basic shapes can be modified with the arity prefix to indicate a different significance, such as BiFunction (a binary function from T and U to R).
  • Additional derived forms exist that extend the basic forms of functions , including UnaryOperator (extends Function) and BinaryOperator (extends BiFunction).

I had not heard of the term “function form” before, and I can hardly find a link to it anywhere except in the above documentation, but since this is formal Oracle documentation on functional interfaces, I would like to understand it.

Can someone give a definition of the "form of function" and come up with an example? Is this a general term in computer science, or does it only apply to Java 8? And how is the form of the function associated with the function descriptor (e.g. (T) → boolean for the Predicate <T> interface)?

UPDATE The two comments below from Brian Goetz answer the questions I raised in this post.

+5
source share
2 answers

The form of the function is basically what its inputs and outputs look like in terms of type parameters:

  • A unary function takes one input and returns one output [T → R]
  • The binary function takes two inputs and returns one output [(T, U) → R]
  • The ternary function takes three inputs and returns one output [(T, U, V) → R]
  • The provider (also known as the null function) does not accept any data and returns a single output [() → R]
  • The consumer takes one input and returns no output [T → ()]
  • A unary predicate takes one input and returns one Boolean type pin [T → bool]
  • The binary predicate takes two inputs and returns one Boolean type pin [(T, U) → bool]
  • The unary operator accepts one input and returns one output of the same type [T → T]
  • The binary operator accepts two inputs of the same type and returns one output of the same type [(T, T) → T]

There are many other forms, but they are common.

+2
source

I did not find a reference to the official or generally accepted definition of the term "form of function", so the following is my own interpretation.

The "form of the function" is represented by its "type signature" , including the return type , i.e. amount description:

  • an ordered list / tuple of types of its parameters and
  • his return type

(That is, basically, everything is about the function, except for the name of the function, parameter names and body.) I suspect that they did not use the term "signature" because it already has a different meaning in Java - it does not include the return type. Therefore, they came up with a new term.

In functional programming languages, "type signature" typically includes a return type. Signatures are useful for understanding what a function can do, so they are often written explicitly. For example, the signature (or “function form” in Java terms) for the new BiFunction can be written as (T, U) -> R , where the first part is a tuple representing a list of parameters, and the second part is the type of the return value,

Therefore, I do not agree with this other answer : I think that these types matter and are not predetermined. If they were rejected, then several types defined in this new namespace would have exactly the same form of function (for example, Supplier , Predicate , Function ). If this were so, then why would the documentation suggest explaining these new types with a mismatched concept of function forms? It does not make sense. (The answer has since been edited.)

Here are some more examples of functional type signatures for the new Java functional interfaces:

 BiFunction<T,U,R>, (T, U) -> R BinaryOperator<T,U,R> (T, U) -> R BiPredicate<T,U> (T, U) -> boolean Consumer<T> T -> () note: `()` means `void` Function<T,R> T -> R IntFunction<R> int -> R Predicate<T> T -> boolean Supplier<R> () -> R UnaryOperator<T,R> T -> R 
+2
source

Source: https://habr.com/ru/post/1204465/


All Articles