Please join me at my new location bryankyle.com

Sunday, February 17, 2008

Curried Functions

So, currying, what's that all about?

Currying is a technique of transforming a function that takes multiple arguments into a function that takes one argument. In short, it's a way of defaulting parameters of a function call.

In a language like Java, you could accomplish the same thing by delegating method calls. For example:

int add(int a, int b) {
   return a + b;
}
int add_one(int b) { return add(1, b) }

However, since functions aren't first class citizens in Java you're limited in what you can do. In a functional language, the possibilities are a more open. You can make use of currying to reduce the size of your code base and reduce the amount of boilerplate code you'd otherwise have to write.

An example of this is a set of accessor methods where the code is boilerplate. Modern IDEs will generate these for you, but wouldn't it be nice if you didn't have to see the code for them all the time? What happens if some of your setters need to manipulate the value being set? I suppose you could find all of the setters and update them manually...or if you're working in a functional language, you could just leverage the features of the language to make your job easier.

Take a look at the following code:

function set(attribute_name, value) {
   this[attribute_name] = value;
}
function get(attribute_name) { return this[attribute_name]; }
function attr_reader(attribute_name) { return function() { return get.call(this, attribute_name); } }
function attr_writer(attribute_name) { return function(value) { set.call(this, attribute_name, value) }; }
function MyClass() {} MyClass.prototype.setName = attr_writer('name'); MyClass.prototype.getName = attr_reader('name');
var o = new MyClass() o.setName('Bryan'); o.getName(); // Bryan

In this example, we have two methods: set and get which are the most simplistic and generic setter and getter functions one could write. We've also added a currying function for each of them. We then call through the currying functions to create a curried call to getter and setters on the prototype of the constructor for MyClass.

While this example is not the best possible code for currying getters and setters I believe it illustrates the concept of currying.

If you can tell me why attr_reader and atter_writer return the functions curried using their call method you get bonus points. If you can't, I'll explain later.