13

I am trying to understand how currying works in functional programming. I have gone through wiki and a couple of questions about the same on SO.

Need help understanding lambda (currying)

What is 'Currying'?

I understand that currying is all about splitting a function that takes n arguments into n or less functions with one argument each. I theoretically comprehend it but I am not able to connect the dots while coding for the same. Perhaps it is my lack of knowledge in functional programming languages or C# (as many answers in the above questions deal with).

Anyway, I understand groovy & java. So I tried to get an outline for the standard add(a,b) function in groovy but I couldn't finish it.

def closure = { arg ->
   // ??
}

def add(anotherClosure , a){
    return closure // ??
}

Can someone help me understand currying using groovy closures?

Community
  • 1
  • 1
Vamsi Emani
  • 10,072
  • 9
  • 44
  • 71
  • 3
    I talk about Functional Programming with Groovy in a conference. You can see the [slides about currying with Groovy](http://www.slideshare.net/arturoherrero/functional-programming-with-groovy/32) – Arturo Herrero May 09 '12 at 08:41
  • Went through all the slides. A very nice piece of information. :) – Vamsi Emani May 09 '12 at 11:09

2 Answers2

17

You can roll your own currying functionality by writing a closure that takes another closure and a curried parameter to set, and returns a closure that uses this value.

// Our closure that takes 2 parameters and returns a String
def greet = { greeting, person -> "$greeting $person" }

// This takes a closure and a default parameter
// And returns another closure that only requires the
// missing parameter
def currier = { fn, param ->
  { person -> fn( param, person ) }
}

// We can then call our currying closure
def hi = currier( greet, 'Hi' )

// And test it out
hi( 'Vamsi' )

But you're better sticking with the inbuilt Groovy curry method as shown by jalopaba. (there is also rcurry and ncurry which curry from the right, and at a given position respectively)

It should be said, that the Groovy curry method is a misnomer as it is more a case of partial application as you do not need to get down to a closure requiring only a single parameter, ie:

def addAndTimes = { a, b, c -> ( a + b ) * c }

println addAndTimes( 1, 2, 3 ) // 9

def partial = addAndTimes.curry( 1 )

println partial( 2, 3 ) // 9
Community
  • 1
  • 1
tim_yates
  • 167,322
  • 27
  • 342
  • 338
12

You can set a fixed value for one or more arguments to a closure instance using the curry() method:

def add = { a, b -> a + b }
def addFive = add.curry(5)
addFive(3) // 5 + 3 = 8

Another example:

def greeter = { greeting, name -> println "${greeting}, ${name}!" }
def sayHello = greeter.curry("Hello")
sayHello("Vamsi") // Hello, Vamsi!
def sayHi = greeter.curry("Hi")
sayHi("Vamsi") // Hi, Vamsi!
jalopaba
  • 8,039
  • 2
  • 44
  • 57