I’ve been toying around with Ruby lately and I found myself wondering if in pure object oriented languages (and even those that are not pure) making methods that take only one parameter and then get chained together is equivalent to currying in languages with a functional style? If not, why not? I’d appreciate a detailed, even rigorous answer on the subject.
Method chaining in object oriented languages is a little different from currying. By definition, the result of currying is a more restricted form of the original function. By convention, the result of method chaining is a modified form of the original (usually non-function) object. Method chaining can be used with unrelated methods on the same class, whereas currying involves returning a function where one or more parameters of the original function are fixed (predetermined).
In Java, method chaining is like:
String myString = new StringBuilder("Hi ").append(firstName)
.append(" ")
.append(lastName)
.append("!")
.toString();
So, each of those .append() method calls returns a pointer to the anonymous StringBuilder object. This object is complete after each .append(), and it is not a function.
By contrast, in Scala, partial application or currying is like:
def simple(x:Int, y:Int, z:Int) = x * (y + z)
val simpler = simple(2, _:Int, _:Int)
simpler(3, 4) => 14
(Sample taken from Daniel Yankowsky’s blog)
simpler()
in this example is a wrapper-function for simple()
. simpler()
is still a function that takes more parameters before it can evaluate to anything but a more limited version of itself.
EDIT: Reading this a day later, I think “wrapper-function” is the key. Currying or partial application might best be simulated in Java with wrapper methods.
public interface Simpler {
public int apply(int y, int z);
}
public class Simple {
public int apply(int x, int y, int z) { return x * (y + z); }
public Simpler partiallyApply(final int x) {
final simple = this;
return new Simpler() {
@Override
public int apply(int y, int z) {
// x is the final int parameter to partiallyApply()
simple.apply(x, y, z);
}
}
}
}
:END-EDIT
Method chaining can be similar to partial application or currying, but it can only be equivalent with methods that return other methods (look up Functors), and then the methods need to be set up with return types that meaningfully model currying or partial application.
Method chaining is more often used to implement something like lazy evaluation, as is done with the “Builder” design pattern and the new Collections Library interfaces in Java 8.
I hope that helps.
4