Update: This post was updated to show the difference between Currying and Partial Functions.
Currying is a concept in Functional Programming that’s enabled by Higher-order functions. It’s best described as: the ability to take a function that accepts n parameters and turns it into a composition of n functions each of them take 1 parameter. Check this function f which takes 3 params x,y,z
f(x,y,z) = 4*x+3*y+2*z
Currying means that we can rewrite the function as a composition of 3 functions(a function for each param):
f(x)(y)(z) = 2*z+(3*y+(4*x))
The direct use of this is what is called Partial Function where if you have a function that accepts n parameters then you can generate from it one of more functions with some parameter values already filled in. Ruby 1.9 comes with support for currying concept(through the Proc#curry method) and this blog post is explaining how you can use it effectively.
I’m going to walk you through a simple example to explain the concept, however i need to mention few things:
1- The main example is taken from the free Scala By Example book(First-Class Functions chapter), however i have replaced recursion calls by simple upto iterators.
2- In Ruby 1.9 you can use block.(*args) just like you use block.call(*args) or block[*args] in Ruby 1.8, so i’ll stick to block.(*) notation.
3- I could have used the inject method, but i preferred readability to concise code.
Let’s start the simple tutorial by adding three methods:
1- A method to sum all integers between two given numbers a and b.
2- A method to sum the squares of all integers between two given numbers a and b.
3- A method to to sum the powers 2^n of all integers n between two given numbers a and b.
################################### # Normal definitions ################################### sum_ints = lambda do |a,b| s = 0 ; a.upto(b){|n| s += n } ; s end sum_of_squares = lambda do |a,b| s = 0 ; a.upto(b){|n| s += n**2 } ;s end sum_of_powers_of_2 = lambda do |a,b| s = 0 ; a.upto(b){|n| s += 2**n } ; s end puts sum_ints.(1,5) #=> 15 puts sum_of_squares.(1,5) #=> 55 puts sum_of_powers_of_2.(1,5) #=> 62
Cool, however if you focus on the 3 methods, you will notice that these methods are all instances of a pattern Σf(n) for a range of values a -> b. We can factor out the common pattern by defining a method sum:
############################################ # Some refactoring to make some abstraction # Passing the sum mechanism itself ############################################ sum = lambda do |f,a,b| s = 0 ; a.upto(b){|n| s += f.(n) } ; s end puts sum.(lambda{|x| x},1,5) #=> 15 puts sum.(lambda{|x| x**2},1,5) #=> 55 puts sum.(lambda{|x| 2**x},1,5) #=> 62
Ok, but what about having the formal definitions for the 3 methods? How can we have those definitions out of the sum method? Well that’s the use of currying and partial functions, in our case we just need to pass the first param to the sum method to specify what type of sum is it:
################################### # More refactoring using currying # Currying was added to Ruby 1.9 # Via Proc#curry ################################### # generate the currying currying = sum.curry # Generate the partial functions sum_ints = currying.(lambda{|x| x}) sum_of_squares = currying.(lambda{|x| x**2}) sum_of_powers_of_2 = currying.(lambda{|x| 2**x}) puts sum_ints.(1,5) #=> 15 puts sum_of_squares.(1,5) #=> 55 puts sum_of_powers_of_2.(1,5) #=> 62
That’s it! I hope I could clarify the use of currying, if not just add your comment here


You can easily do this in Ruby 1.8 with:
class Proc
def curry(arg)
lambda {|*args| self.call(arg,*args)}
end
end
@Shalev, Thanks, the following one is more enhanced:
The curry definitions given here mess with Proc#arity, don’t they? In other words:
lambda { |x,y| x + y }.arity => 2
class Proc
def curry(*p)
lambda {|*args| self.call(*(p+args))}
end
end
lambda { |x,y| x + y }.curry(1).arity => -1
I would expect the ‘curried’ function to have an arity of one. Also, is this currying or partial application?
@Reg, as for the arity, i have tried that in Ruby 1.9 and got the same result -1, it’s odd though.
As for the previous code, you are true, that’s a partial function definition, not a currying one. I’ll post a better snippet soon.
Pingback: Twitted by gnupate
the arity problem is easy to solve
http://drawohara.com/post/113308029/ruby-a-curry-function-for-ruby
regards.
-a
Pingback: 僕の考えたカリー化 « **deadwinter**
Pingback: curried function