Closed jpotterm closed 10 years ago
Instead of making this change specific to only 2 arguments, what if the fn.flip
by default flips the same number of arguments as the arity of the handler, otherwise a specified number or arguments?
I think making flip specific to 2 arguments is a good thing. That's the way it is defined in every functional language I've ever seen (if you know of an exception, let me know). Flip should be used sparingly anyway, but I think using it on more than 2 arguments would make your code unreadable very quickly. It's main use case (in my opinion) is to curry the second parameter of a binary operator.
If you wanted to curry the fourth parameter instead, I'd expect the clearest way to do that would be a function that moved the fourth parameter the front and left the other parameters in the same order. Something like:
flipN(4, function(a, b, c, d) {}); // function(d, a, b, c)
The only case I can think of where reversing the arguments would be at all useful is if you wanted to curry the second and third arguments but not the first. And even in that case I think your code would be much more readable if you defined a wrapper function.
So in summary, I don't think flip is a very useful function to generalize, but if we were going to generalize it, I think a function that moved the n
th argument to the front would be much more useful than reversing the arguments.
Do you have a use case in mind for reversing the arguments?
I think the semantics for having a function named flip
assumes that you are going to be flipping the arguments of a given function, and that means all arguments. If we need a function to do specific reordering of a function's arguments, I think a new method should be introduced.
Well from what I've seen, flip
functions from other languages are only defined for 2 arguments. So I don't think it's clear that the extrapolation to n
arguments is reversal.
The word itself might imply reversal, but I think that's because it was only ever meant to apply to two arguments. So I guess I'm saying that if we are trying to keep what people are used to, then it should only flip the first 2 arguments. If we're trying to generalize it to n
arguments (which people won't expect), the only useful way (IMO) seems to be moving the n
th argument to the front.
Yes, fn.flip
's semantics are going to be defined as a general way to reverse the order or arguments of a given function. That may be bucking a trend, but I see it as a good thing. Like I said, if we need to have another method for re-ordering arguments, I'm all for it.
Ok, do you think I should submit this functionality under a function with a different name (e.g. fn.swapArgs)? I feel like both functions would have extremely similar use cases, and I don't want to clutter the API.
Just so you know, the reason this came up for me was that I was trying to flip a binary operator and pass it to filter:
var eq2 = fn.partial(fn.flip(fn.op['===']), 2);
fn.filter(eq2, [1, 2, 3, 4]); // Expected: [2], actual: []
Currently, flip will reverse all the arguments. This is a problem when working with functions that take optional arguments at the end. For example, say you have:
where
includeNewline
is an optional argument. You probably flipped it so you could partially applyb
:The problem is that the argument you just partially applied is either
b
orincludeNewline
depending how many arguments you call it with:and this was not the intention.
I think flip only really makes sense for the first two arguments anyway, and the use case is nearly always to partially apply the second argument. So this pull request makes flip only swap the first two arguments and leave the others in the same order.