Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Java support Currying?

I was wondering if there is any way to pull that in Java. I think it is not possible without native support for closures.

like image 592
user855 Avatar asked May 26 '11 05:05

user855


People also ask

What is currying in Java?

Advertisements. Currying is a technique where a many arguments function call is replaced with multiple method calls with lesser arguments. See the below equation. (1 + 2 + 3) = 1 + (2 + 3) = 1 + 5 = 6. In terms of functions: f(1,2,3) = g(1) + h(2 + 3) = 1 + 5 = 6.

Is currying supported in scheme?

It is possible to generate curried functions in Scheme. The function curry2 generates a curried version of a function, which accepts two parameters. The curried version takes one parameter at a time. Similarly, curry3 generates a curried version of a function that takes three parameters.

What is the benefit of currying?

Currying is helpful when you have to frequently call a function with a fixed argument. Considering, for example, the following function: If we want to define the function error , warn , and info , for every type, we have two options. Currying provides a shorter, concise, and more readable solution.

What is currying FP?

My least jargon filled way of answering that question is this: Currying is the act of refactoring a function that normally receives all its arguments at once into a series of functions that only take one argument at a time. In JavaScript, functions can receive any number of arguments.


2 Answers

Java 8 (released March 18th 2014) does support currying. The example Java code posted in the answer by missingfaktor can be rewritten as:

import java.util.function.*; import static java.lang.System.out;  // Tested with JDK 1.8.0-ea-b75 public class CurryingAndPartialFunctionApplication {    public static void main(String[] args)    {       IntBinaryOperator simpleAdd = (a, b) -> a + b;       IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;        // Demonstrating simple add:       out.println(simpleAdd.applyAsInt(4, 5));        // Demonstrating curried add:       out.println(curriedAdd.apply(4).applyAsInt(5));        // Curried version lets you perform partial application:       IntUnaryOperator adder5 = curriedAdd.apply(5);       out.println(adder5.applyAsInt(4));       out.println(adder5.applyAsInt(6));    } } 

... which is quite nice. Personally, with Java 8 available I see little reason to use an alternative JVM language such as Scala or Clojure. They provide other language features, of course, but that's not enough to justify the transition cost and the weaker IDE/tooling/libraries support, IMO.

like image 131
Rogério Avatar answered Sep 30 '22 02:09

Rogério


Currying and partial application is absolutely possible in Java, but the amount of code required will probably turn you off.


Some code to demonstrate currying and partial application in Java:

interface Function1<A, B> {   public B apply(final A a); }  interface Function2<A, B, C> {   public C apply(final A a, final B b); }  class Main {   public static Function2<Integer, Integer, Integer> simpleAdd =      new Function2<Integer, Integer, Integer>() {       public Integer apply(final Integer a, final Integer b) {         return a + b;       }     };      public static Function1<Integer, Function1<Integer, Integer>> curriedAdd =      new Function1<Integer, Function1<Integer, Integer>>() {       public Function1<Integer, Integer> apply(final Integer a) {         return new Function1<Integer, Integer>() {           public Integer apply(final Integer b) {             return a + b;           }         };       }     };    public static void main(String[] args) {     // Demonstrating simple `add`     System.out.println(simpleAdd.apply(4, 5));      // Demonstrating curried `add`     System.out.println(curriedAdd.apply(4).apply(5));      // Curried version lets you perform partial application      // as demonstrated below.     Function1<Integer, Integer> adder5 = curriedAdd.apply(5);     System.out.println(adder5.apply(4));     System.out.println(adder5.apply(6));   } } 

FWIW here is the Haskell equivalent of above Java code:

simpleAdd :: (Int, Int) -> Int simpleAdd (a, b) = a + b  curriedAdd :: Int -> Int -> Int curriedAdd a b = a + b  main = do   -- Demonstrating simpleAdd   print $ simpleAdd (5, 4)    -- Demonstrating curriedAdd   print $ curriedAdd 5 4    -- Demostrating partial application   let adder5 = curriedAdd 5 in do     print $ adder5 6     print $ adder5 9 
like image 41
missingfaktor Avatar answered Sep 30 '22 00:09

missingfaktor