Why is curry not popular among Rubyists?

I’ve been wondering this one for a while. In fact, as much as I like functional programming, most of the time my Ruby functions are not curried or partially applied in any way. I guess this is because I have always thought of Ruby as a very paradigmatic Object Oriented language, where absolutely everything is an object, Smalltalk is at its core and even I do find myself writing code in lambdas and blocks all the time like most Ruby programmers do, I’ve stayed away from curry and partial application in production code.

If I was asked why do I do this, I would say it’s just a matter of following the best Rubyists style, and keeping my code easy to understand for newbies. The former argument is weak at best –fallacious argument from authority– while the second one is true, but I consistently use other advanced features that newbies won’t understand at a first glance. Moreover, lazy evaluation is about to come in Ruby 2.0 and I am very, very positive its use will become very widespread.

If you care about this and treat it as a problem, it’s probably just a matter of being afraid of criticism for not adhering to the rules. It’s so easy to follow that route and shun from challenging the state of things. I’ll make a conscious effort from today on using it unless someone raises a valid point against using these two functional approaches in Ruby code. And to start off I am going to give a brief overview of it in this post.

In any case, Ruby core thought it was a good idea and allows us to make curried Procs from 1.9 on. So here is what I understand as currying and partial application in Ruby, how to do it, you can draw your own conclusions.

Currying is a concept that allows a function that takes N parameters to be a composition of N functions, each of them take 1 parameter.

If you are looking at this and your eyebrow is raising,  bear with me for one minute.

Functions have arguments. When a function is called using all its arguments it means we are applying all of the arguments to the function we are calling to. In the non-curried function above, we are applying ‘x, y, z’ to the function.

Curried functions allows us to define new functions in terms of partially applied functions. A few examples will clarify how this is relevant and very useful feature in a programming language.

The original way (ML family of languages):

Many functional languages will let you write  “f x y z".  If you call “f x y" then you get a partially-applied function—the return value is a closure of lambda(z){z(x(y))} with passed-in the values of x and y to f(x,y).

The Ruby way:

Partial application is not as natural to write in Ruby as it is in Haskell or SML. Functions are not curried by default and in fact the way to do this is to curry the function ourselves, then define new partially applied functions upon the curried function. This is a simple function that only adds up numbers from a to b, applying f to them.

The power that partial application is giving us here is that we can very easily define new functions that build up on sum by using partial application. 

For instance,  we can partially apply the function f, and get a function ‘sum_of’_squares’ that only requires the start and end of the interval.

Or we can even partially apply the function f and the start of the interval a, and provide a more specific function:

Of course we can pass functions that remove prime numbers from the sum, start the interval or end it wherever we want[1]. These are all useful things when building a set of abstractions for your domain. Will you start to use them?

 

[1]: Actually no, we have only explored leftmost currying in this article. Rightmost currying is not currently implemented in Ruby, I’ll do my best to have it ready for 2.0.0

[2]: Last but not least, here’s an example of an interesting use of partial application in a context, by PragDave aka The Pragmatic Programmer.