Groovy Functional Programming - Currying

One of the design techniques used in functional programming is to create a generic functions and derive special functions from the generic ones by fixing some of the arguments. To understand this consider the following use-case.

We want to be able to double, triple and quadruple numbers. We can write the following closures.

def doubler = { number ->
    number * 2
}

def triple = { number ->
    number * 3
}

def quadruple = { number ->
    number * 4
}

println doubler(10) // 20
println triple(10) // 30
println quadruple(10) // 40
If you are not familiar with closures, this article has the necessary details.

Let's create a generic closure to multiply two numbers and achieve the same results.

def multiply = { times, number ->
    times * number
}
println multiply(10, 2) // 20
println multiply(10, 3) // 30
println multiply(10, 4) // 40

It works, but not as intuitive or readable as before. Now let's use currying to derive the closures which can double, triple and quadruple.

def doubler = multiply.curry(2)
def triple = multiply.curry(3)
def quadruple = multiply.curry(4)

println doubler(10) // 20
println triple(10) // 30
println quadruple(10) // 40

Here the method curry creates a new closure by fixing the first argument for multiply. Thus the returned closure has only one argument, which is number.
While curry starts fixing the arguments from left, Groovy also provides other variants of currying.

The method rcurry can be used if you want to fix values for the parameters of right most ones.

rcurry does not apply values from right to left. If your original closure has 3 parameters, and if you want to fix the second and third parameters, the first argument to rcurry should be the value for the second parameter, followd by the value for the third parameter.

The method ncurry will fix parameters starting from a specified position

Note: Some languages/ libraries distinguish between partial application and currying. In such cases currying is fixing parameters one at a time, while with partial application, you can fix multiple parameters in a single shot. However in Groovy, no such distinctions exist.

You may want to take a look at slides from my FunctionalConf talk for more examples.

Show Comments