Unexpected behavior of curry and curryN
See original GitHub issueHello,
First of all, thanks for ramda, it’s a great tool for FP.
Today, trying to make some testing I almost became mad because my tests were not executing properly. I blamed node, my testing tool and my testing environment. Then I realized the problem was with lodash.curry
. Why am I here then ? Because I thought:
“Ok lodash did it wrong, let’s see if ramda does the same.”
And happens that ramda does exactly the same. I can accept that maybe the person who is wrong is me, but not a single line in the documentation mentions the behavior I have discovered.
Here is a small snippet you can test on ramda REPL
const x = curry((a,b,c) => console.log(a,b,c))
x()('b')('c')()()()()('a')
const y = curryN(3,(a,b,c) => console.log(a,b,c))
y()('b')('c')()()()('x')
As you can see I can call x
and y
as many times as I want if I don’t provide an argument. My expectation is that, if the function takes three parameters, the curried function is executed after being invoked 3 times.
Functions communicate their arity with the length property, so there curry can easily track function invocations and compare them with the arity.
Maybe I can accept that behavior on curry, but the I want to have an escape hatch on curryN
, but that is not the case.
Imagine that I have a curried function that takes an optional parameter, I can’t use ES6 defaults because then curry will not work, so I try to check default inside the function.
const x = curry((a,b,c) => {
a = a || 'default'
console.log(a,b,c)
})
This will not work either because I’ll be forced to call the function like this
//not working
x()('b','c')
// works
x(null)('b','c')
As I said, I can accept this behavior for curry, but not for curryN
.
And even if you want to keep it the way it is, please document this particular behavior on the documentation.
Regards
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (4 by maintainers)
It’s not really that they’re optional that’s at issue. The problem is that when JS decided to add defaults values for parameters, it chose to not count those with defaults when reporting the function’s arity.
So we’ve already lost the ability to curry it with just plain
curry
, which uses that length.But even beyond that, it’s very hard to know what to do with such arguments given Ramda’s style of currying. We could switch to straightforward currying, and forget any calls with multiple parameters. (And there’s a fair bit to be said for this, but it’s a radical change to Ramda.) Or we could invent a second kind of placeholder to say “use the default here.” But this seems extravagant for the gain.
But mostly, I think what David said is appropriate: Optional parameters and currying are two different and incompatible solutions to a single problem.
I have never seen a pattern where the first argument is optional? You can use
curryN
to support optional arguments at the end however, if you would like:https://goo.gl/2YnmPa