## Wednesday, November 13, 2013

### Basic Currying Function in Dart

I continue to explore currying in Dart tonight. I have struggled with currying in Dart since a ways back. Actually, I should clarify that. I have struggled with a general purpose `curry()` in Dart.

It is quite easy to manually curry a function Dart. Consider the venerable `add()` function that simply adds three numbers:
```add(x, y, z) {
return x + y + z;
}```
I can write a not-too-longhand curry of that as:
```curriedAddManual(arg1) =>
(arg2) =>
(arg3) =>
The hash-rocket is Dart's syntactic sugar for return-what-i-am-pointing-at. So `foo() { return 'foo'; }` can be more succinctly written as `foo() => 'foo';`

So the `curriedAddManual()` takes a single argument and returns a function. The returned function takes a single argument and returns a function. Finally, that returned function takes a single arguments and returns the result of adding all three arguments. In other words, I have converted `add(1, 1, 1)` to `curriedAddManual(1)(1)(1)`. That is the very definition of currying: converting a function that takes multiple arguments into a chain of functions that each take a single argument.

There are lots of good reasons to curry. There are many good articles on the JavaScript variety of currying that give reasons why one might want to curry, so I am not going to dwell on them too much. I will note that Dart's first class support of futures make curried functions quite attractive.

I believe that, after last night, I have the pieces necessary to write a curry function. At least the simple variety that can convert a function with an arbitrary number of arguments into a function that takes a single argument. The JavaScript version looks something like:
```curry(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
return fn.apply(
this,
args.concat(
Array.prototype.slice.call(arguments)
)
);
};
};```
This `curry()` function takes a function argument along with an arbitrary list of additional arguments. It returns a function that, when called with a single argument (i.e. when curried), will invoke the function with that single argument plus the list of arguments supplied to the `curry()` function.

Ah, the chicanery of `Array.prototype.slice()` in JavaScript. In the static-like world of Dart, the easiest way to get arguments that act like a list does not involve stuff like that, but it is not trivial. The easiest way to get access is via a `noSuchMethod()` definition in a class:
```class Curry {
noSuchMethod(args) {
if (args.memberName != #send) return super.noSuchMethod(args);
return _curry(args.positionalArguments);
}
// ...
}
```
The `args` object that is passed into `noSuchMethod()` is an `Invocation` object with useful properties like `positionalArguments`—the list of arguments supplied in order when the method was called. I do not strictly need to check that the method name (`memberName`) is `send()`, but I try to be a good citizen by checking for the `#send` symbol.

As for the `_curry()` method itself, it is fairly simple:
```class Curry {
noSuchMethod(args) {
if (args.memberName != #send) return super.noSuchMethod(args);
return _curry(args.positionalArguments);
}

_curry(args) {
var fn = args[0],
bound = args.sublist(1);

return (_) {
return Function.apply(fn, _args);
};
}
}
```
The first parameter is the function being curried. The remaining arguments are the bound list of arguments. The `_curry()` method will return a function that takes a single argument (`_`). That single argument combined with the bound list become the entire list of arguments that will be supplied to the curried function when it is invoked.

With that, I can curry the `add()` method as:
```var curried = new Curry().send(add, 1, 2);
curried(3) //  6```
Going through a class like that is still somewhat roundabout. I will see if I can make that a little less opaque. I would also like to see if I can convert that to a true curry function—something that generates a chain of one argument functions. Tomorrow.

Day #934

1. 1.) "That is the very definition of currying: converting a function that takes multiple arguments into a chain of functions that each take a single argument."

Right. But the currying is the conversion, and not the result. And therefore your first example (curriedAddManual) may be a bit misleading. A first approach could be to introduce a first automatic currying step, where only the number of parameters is fixed:

curry3(f) => (arg1) => (arg2) => (arg3) => f(arg1, arg2, arg3);

This would convert any 3-parameter functions into its curried form. The only last task is to abstract over the amount of parameters.

2.) Your second example ( _curry(args)) is indeed NOT currying but partial function application: You take a multi param function and immediately apply all but one parameters ( send(add,1,2) ), resulting in a function that takes the remaining one immediately giving the end result.
I.e.: the following is not possible: