Live data from Hacker News

Currying vs. Partial Application (2015)

datchley.name

11–20 of 54 posts

Re: Currying vs. Partial Application (2015)

#11
Ok, it might be too early in the morning, but I still don't understand this. I read that post, and the post by 'raganwald that the former linked to, and I still don't see any difference between currying and partial application. And yet both posts seem to imply (without showing in any way) that the two concepts are different. How come?

Re: Currying vs. Partial Application (2015)

#12
post #5

I love how the new arrow syntax makes curried functions incredibly simple. const fn = a => b => c => { return a + b + c; };

appear incredibly simple*️

In what way is it not simple? It's hard to tell what you mean. The syntax is actually a bit of a nightmare if you are writing a parser, but from the perspective of a human reader, it shows you exactly what's going on under the hood.

Re: Currying vs. Partial Application (2015)

#13

Ok, it might be too early in the morning, but I still don't understand this. I read that post, and the post by 'raganwald that the former linked to, and I still don't see any difference between currying and partial application. And yet both posts seem to imply (without showing in any way) that the two concepts are different. How come?

Here's a nice write-up that originally helped me understand currying:

https://hughfdjackson.com/javascript/why-curry-helps/

Basically a curried function could be described nested series of partially applied functions(one argument per step).

On a side note to me this article is a bit on the heavy side when it comes to conveying the message. For one thing partial application should be explained first.

Re: Currying vs. Partial Application (2015)

#14

Currying in JavaScript is really nice if you can remember the arities of each curried function you're using. If you forget to call up to the last argument, you'll be passing a curried function instead of the expected value, and it can throw an error really far away from the bug. And instead of normal data to inspect at the error site to point you to the bad call, you'll only have a generic function name to look at. I…

I've been using currying (via http://ramdajs.com/) in my projects for a while now and this is rarely a problem(yay for anecdotal evidence).

One reason for that is that my curried functions and their derivatives are usually named in a way that says exactly what they do.

Re: Currying vs. Partial Application (2015)

#16
post #4

I wrote my own curry using the pareto principle - this works for 80% of my use cases (or more): const curry = (fn,b) => (a) => fn(a,b);

Are you typically not binding the first parameter? Why?

It's a right curry (which I can reapply for N args). It's just personal preference, but I like to write "function templates" and then "particularize" them with a curry, from right to left. The direction is unusual but it's a personal choice and arbitrary.

Re: Currying vs. Partial Application (2015)

#17

Ok, it might be too early in the morning, but I still don't understand this. I read that post, and the post by 'raganwald that the former linked to, and I still don't see any difference between currying and partial application. And yet both posts seem to imply (without showing in any way) that the two concepts are different. How come?

Partial application (passing too few arguments to a function) is something that a programmer does. Function currying is something that a programming language does in response to partial application. It's basically wrapping the partially applied function in another one that expects the missing arguments and then performs the originally intended computation.

Re: Currying vs. Partial Application (2015)

#18
post #6

Currying in JavaScript is really nice if you can remember the arities of each curried function you're using. If you forget to call up to the last argument, you'll be passing a curried function instead of the expected value, and it can throw an error really far away from the bug. And instead of normal data to inspect at the error site to point you to the bad call, you'll only have a generic function name to look at. I…

The type of a curried function in Typescript is just something like: (a: number) => (b: number) => (c: number) => number Sure, the parameter names and parentheses are a bit annoying, but I wouldn't call that "very verbose". Comparable concepts in C++ or Java would be a nightmare to type out.

I can't speak to Typescript but check out the Flow types for Ramda: https://github.com/flowtype/flow-typed/blob/master/definitio...

Maybe just a matter of perception but it looks verbose to me.

Re: Currying vs. Partial Application (2015)

#19

Ok, it might be too early in the morning, but I still don't understand this. I read that post, and the post by 'raganwald that the former linked to, and I still don't see any difference between currying and partial application. And yet both posts seem to imply (without showing in any way) that the two concepts are different. How come?

Partial application is applied on call site, currying at definition.

Currying:

    const f = x => y => x + y;

    const g = f(1);

    const sum = g(2);
 
Partial application:

    const f = (x, y) => x + y;

    const g = _ => f(1, _);

    const sum = g(2);
Most FP languages have nicer syntax for this.

Re: Currying vs. Partial Application (2015)

#20
post #6

Earlier quoted context omitted.

The type of a curried function in Typescript is just something like: (a: number) => (b: number) => (c: number) => number Sure, the parameter names and parentheses are a bit annoying, but I wouldn't call that "very verbose". Comparable concepts in C++ or Java would be a nightmare to type out.

I agree, that doesn't look bad. However, this type definition forces you to supply one argument per function call, which looks awful in JavaScript: fn(1)(2)(3) That's a big drawback for me. Libraries like Ramda allow one or more arguments per function call: fn(1, 2, 3) === fn(1, 2)(3) === fn(1)(2, 3) That's what makes the verbosity unbearable, as each type of call needs its own type.

At least in Flow it's actually possible to properly type curried functions!

Here's a gist of the type definitions I'm using: https://gist.github.com/noppa/c600cc43fd44e33768efe6c6eec4a9...

I think something similar might work in TS too.

Demo: https://goo.gl/w3aPsw

Post reply on HN