Does groovy call partial application ‘currying’

functional programminggroovy

Groovy has a concept that it calls 'currying'. Here's an example from their wiki:

def divide = { a, b -> a / b }

def halver = divide.rcurry(2)

assert halver(8) == 4

My understanding of what's going on here is that the right hand argument of divide is being bound to the value 2. This seems like a form of partial application.

The term currying is usually used to mean transforming a function that takes a series of arguments into a function that only takes one argument and returns another function. For example here is the type of the curry function in Haskell:

curry :: ((a, b) -> c) -> (a -> (b -> c))

For people who haven't used Haskell a, b and c are all generic parameters. curry takes a function with two arguments, and returns a function that takes a and returns a function from b to c. I've added an extra pair of brackets to the type to make this more clear.

Have I misunderstood what's going on in the groovy example or is it merely misnamed partial application? Or does it in fact do both: that is to say convert divide into a curried function and then partially apply 2 to this new function.

Best Answer

Groovy's implementation of curry does not actually curry at any point, even behind the scenes. It is essentially identical to partial application.

The curry, rcurry and ncurry methods return a CurriedClosure object that holds the bound arguments. It also has a method getUncurriedArguments (misnamed—you curry functions, not arguments) which returns the composition of the arguments passed to it with the bound arguments.

When a closure gets called, it ultimately calls the invokeMethod method of MetaClassImpl, which explicitly checks to see if the calling object is an instance of CurriedClosure. If so, it uses the aforementioned getUncurriedArguments to compose the full array of arguments to apply:

if (objectClass == CurriedClosure.class) {
    // ...
    final Object[] curriedArguments = cc.getUncurriedArguments(arguments);
    // [Ed: Yes, you read that right, curried = uncurried. :) ]
    // ...
    return ownerMetaClass.invokeMethod(owner, methodName, curriedArguments);
}

Based on the confusing and somewhat inconsistent nomenclature above, I suspect that whoever wrote this has a good conceptual understanding, but was perhaps a little rushed and—like many smart people—conflated currying with partial application. This is understandable (see Paul King's answer), if a little unfortunate; it will be difficult to correct this without breaking backwards compatibility.

One solution I've suggested is to overload the curry method such that when no arguments are passed it does real currying, and deprecate calling the method with arguments in favour of a new partial function. This might seem a little strange, but it would maximise backwards compatibility—since there's no reason to use partial application with zero arguments—while avoiding the (IMHO) uglier situation of having a new, differently-named function for proper currying while the function actually named curry does something different and confusingly similar.

It goes without saying that the result of calling curry is completely different from actual currying. If it really curried the function, you would be able to write:

def add = { x, y -> x + y }
def addCurried = add.curry()   // should work like { x -> { y -> x + y } }
def add1 = addCurried(1)       // should work like { y -> 1 + y }
assert add1(1) == 2 

…and it would work, because addCurried should work like { x -> { y -> x + y } }. Instead it throws a runtime exception and you die a little inside.