• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Java 8 - is it really doing function currying?

 
Ranch Hand
Posts: 239
12
Scala IntelliJ IDE Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was reading this article on how Java 8 doesn't really have currying. I looked around the web and a lot of examples are out there using the lambda syntax (->) but all they are doing is using it as syntactic sugar for:



"add2" method here is not a curried function. It just forwards along to another method.

So does Java 8 really have function currying?? I've been using Scala for awhile now which has real function currying.
 
Author
Posts: 161
31
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Scott,

Being the author of this article, my opinion is probably biased! However, to the exact question "does Java 8 really have function currying in the same way Scala has?", the answer is no. But neither Scala not Java "have" function currying. What Scala has is syntactic sugar for function currying. Function currying is not a feature a language has or has not.

First, one must acknowledge the fact that there is no such thing as a function of several arguments. A function is an application from a set to another set. It can't be an application from several sets to one set. So it can only have one argument. What people call functions of several arguments are in fact functions of tuples. For example, the following function:

is a function of one argument, the tuple (x, y), which is a single element of the product of two sets, and the product of two sets is a single set. If x and y are positive integers, (x, y) is an element of the set of all possible pairs of positive integers.

In Java 8, a function may be represented by a method, such as:

or by a function:

or by a method reference:

(Note that properties and method may have the same name, although this does not make things easy to read!)

Currying is useful in many cases if you need the two values of the tuple to be evaluated separately. For example, you may use the f function to compute the area of rectangles. But if you have rectangles of width 2, 3 and 4 and varying length, it could be useful to build three specialized functions for this: f2 for computing the area of rectangles of width 2, f3 for rectangles of width 3, and so on.

You can write specific methods or functions for this, from scratch, such as:

or

But this is not at all currying. Currying is the fact to write a function that is equivalent to f but that allows applying each element of the tuple argument one at a time, as if one could write:

but this of course does not compile. For this, one need to write a curried version of the function. Applying the first argument will return a function taking the second argument. Thus the type of the function is:

where is the argument type, and is the return type.

As you can see, there is no way to do this with methods, since you can't return a method. You can however return a method reference, but the type is still a function. The complete curried function is:

This is currying. So you can't say that a language has it or not. It's up to you to implement it. What Scala has is syntactic sugar for applying functions. The computation of the area of a rectangle of width 2 and length 5 could be written in Java as:

or

In Scala, one can write:

Beside this syntactic sugar, currying in Java is done exactly as in Scala.

Two things are worth noting:
  • Using the curried form allows writing function of "any number of arguments" where Java 8 only has BiFunction.
  • Using the curried form does not allow using method references (at list in a simple way), so it might not allows as much optimization from the compiler and/or the JVM

  • For more information about currying, see my book Functional Programming in Java in which I also present automatic currying an uncurrying.


     
    Saloon Keeper
    Posts: 15524
    364
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Great detailed answer Pierre-Yves!

    The only thing I can add is an example of how currying works in a purely functional language such as Haskell.

    Let's take the foldl function, which takes a binary operator, an identity and a list of elements, and folds (or reduces) the list by applying the operator to all the elements of the list. Here's the declaration:

    You can use it to sum a list of numbers:
    This expression returns 0+1+2+3=6.

    To make this less onerous we can define the sum function:

    We provided the foldl function with an operator, and got a function that takes a number and a list of numbers, and which returns a number.

    Then we provided *that* function with the additive identity 0, and got a function which takes a list of numbers, and returns the sum of that list.
     
    Don't get me started about those stupid light bulbs.
    reply
      Bookmark Topic Watch Topic
    • New Topic