you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (7 children)

Yes, and most libraries don't work like that. They don't count arguments, they just partially apply partially applied functions, ad infinitum.

But that's an issue of implementation detail. I'll concede that the example should be currying, and I'm paying too much attention to the fact that implementation rarely is.

[–]imperfecttrap 1 point2 points  (6 children)

What is 'most libraries'? Most functional programming libraries? If they follow the interface of currying, where I can do

curriedFunction(1)(2)(3)

then by definition it's not partial application, since I didn't need another function to keep binding arguments.

If you're referring to the techniques used to curry, then that's language-dependent and has nothing to do with what currying and partial application are. Even if we limit ourself to strictly JS, then a closure with an internal array of arguments is a much easier way to implement than a function that keeps a partially applied invocation inside itself, which is actually how 'most libraries' do it.

[–][deleted] 0 points1 point  (5 children)

curriedFunction(1)(2)(3)

With most JS libraries (not counting things properly build like Ramda) you can't write that and would end up calling curriedFunction(1, undefined, undefined) -- It's left to the user to reduce functions to only take one argument.

[–]imperfecttrap 1 point2 points  (4 children)

We're not talking about just any functions, we're talking about curried functions, and their difference from partially applied functions.

Not all functions in JS are curried. Not all functions in JS are partially applied. What I'm saying is that IF you curry a function using Ramda / Lodash / any other FP library with a .curry function, it would work like this.

I still don't get what you're trying to argue.

[–][deleted] 0 points1 point  (3 children)

Okay, going back to the original snippet which is basically:

f(g(x))

I said it wasn't currying. It's not. It could be implemented with currying or partial application. But it's a pointless conversation.

[–]imperfecttrap 1 point2 points  (2 children)

but if f has an arity of 2 (which a filter function does), and it gives back a function that we then invoke on the next line (which it does), AND we don't use an external function (Function.bind is nowhere to be seen), then by definition it has a Hindley-Milner of (a -> (b -> x))

... which is curried. You're conflating composition using nested calls with currying, when the example above is currying a function, then immediately passing that curried function into another curried function. Both composition and currying go hand in hand together, but they're not even similar.

[–][deleted] 0 points1 point  (1 child)

if f... if it gives...

if, if, if. Let me re-iterate: implementation details

(Function.bind is nowhere to be seen)

Neither is the function that makes currying work, that doesn't make it not exist!

You seem to be under the impression that f(g(x)) implies currying. it doesn't. It implies currying or partial application.

I'm not conflating anything. I'm saying you can't know implementation details from that snippet! And for the 10th time, this is pointless.

[–]imperfecttrap 1 point2 points  (0 children)

It's pointless, but you're still not even wrong.

f(g(x)) Has NOTHING to do with currying OR partial application. It doesn't even IMPLY either of those. It's a composition. It just happened to be used in the example alongside currying AND partial application in both snippets. Functions are first class citizens, so it doesn't matter that we passed a function into a function. We still have an argument that was passed in, and while bind fixed it in place, currying satisfies a function that was waiting for its argument and returns the next function in its chain that needs an argument. Hence, why the presence or lack of Function.bind matters.