About currying: https://en.wikipedia.org/wiki/Currying
Since C# 6 introduced expression bodied members, it made a huge step towards more comfortable currying:
``` C#
Func
``` C#
var five = Substract(10)(5);
var substractFromFive = Substract(5);
var one = substractFromFive(4);
But still there are a few rough edges:
Func<int, Func<int, int>> Multiplicate(int mul1) => (int mul2) => (int mul3) => mul1 * mul2 * mul3;var product = Multiplicate(2)(3)(4);Therefore I propose that following should be allowed:
``` C#
//ommited arrows between parenthesis and return type defined as for last method in chain
int Substract(int minuend)(int subtrahend) => minuend - subtrahend;
which would behave like:
``` C#
int Substract(int minuend, int subtrahend) => minuend - subtrahend;
Func<int, int> Substract(int minuend) => (int subtrahend) => Substract(minuend, subtrahend);
It seems important to note that:
``` C#
bool Compare
var objectEqualityComparer = Compare
- Results from partial call (call with subset of parameter blocks) to curried function should be again callable as curried function (with multiple parameter blocks in single parenthesis):
``` C#
int Multiplicate(int mul1)(int mul2)(int mul3) => mul1 * mul2 * mul3;
var multiplyBy5 = Multiplicate(5);
var thirty = multiplyBy5(2, 3);
``` C#
int Substract(int minuend)(int subtrahend) { return minuend - subtrahend; }
# Implementation
Unfortunately, this can't be solved by simply generating more overloads for curried methods because their number grows exponentially. So maybe mark curried methods with some attribute and make jitter take care of that, but I assume that would require CLR support which would be unfortunate. Maybe give up performance improvements and memory savings and simply translate calls `Multiplicate(5, 2, 3)` to `Multiplicate(5)(2)(3)` but that would discard one of the motivations for this proposal – performance improvements.
Clearly this needs insight from someone smarter than me, with deeper knowledge of CLR.
## Generated delegate types
Since delegate type declaration is omitted from curried function declaration, it raises a question which types should be generated by the compiler. Implicit delegate conversions as mentioned in #14 would solve this issue, but it seems it has fallen out of favor.
Therefore I would propose for delegates to be combined by default from standard `Func<...>` and possibly single trailing `Action<...>` if the whole function returns void.
However this behavior should be configurable if necessary. I have thought of two possible solutions, both utilizing attributes (targeting either Method or ReturnValue).
### Option 1
Attribute constructed with single parameter containing Type describing return type of function as called with only first parameter block (i.e. exactly the same you would have to write without currying syntax support).
``` C#
[AttributeUsage(AttributeTargets.ReturnValue)] //or AttributeTargets.Method ?
public class CurryAsAttribute : Attribute
{
public CurryAsAttribute(Type type);
}
``` C#
//forces ExceedsThreshold(10) to return Predicate
[return: CurryAs(typeof(Predicate
bool ExceedsThreshold(int threshold)(int value) => value > threshold;
This approach would be much more complex with generic curried functions. It would probably require partially bound generics as (more or less) discussed in #3993.
### Option 2
Attribute constructed with list of unbound Types, each describing return type of one parameter block.
``` C#
[AttributeUsage(AttributeTargets.ReturnValue)]
public class CurryAsAttribute : Attribute
{
public CurryAsAttribute(params Type[] types);
}
C#
//forces Compare<T> to return Func<T,Predicate<T>>
[return: CurryAs(typeof(Func<,>), typeof(Predicate<>))]
bool Compare<T>(Func<T, T, bool> comparer)(T item1)(T item2) => comparer(item1, item2);
This would construct the actual return type starting from the right:
Predicate<> which returns bool so its fine. If it were something like Func<,> then bool would be supplied as second type parameter. Predicate type parameter is inferred from T item2 resulting in Predicate<T> Func<,> so previously fixed Predicate<T> is supplied as second type parameter. First type parameter is inferred from T item1 resulting in Func<T,Predicate<T>>Other related proposals: #3171
Why does this need a new syntax or CLR changes? Why should the function have to be declared in a different manner to support currying? I already use currying and partial application very frequently just with lambdas at the consumer.
public int Substract(int minuend, int subtrahend) => minuend - subtrahend;
///
Func<int, int> subtractBy5 = (minuend) => Subtract(minuend, 5);
Func<int> subtract10By5 = () => subtractBy5(10);
int result = subtract10By5();
Debug.Assert(5 == result);
Is there a reason that this method is insufficient? Syntactically being able to infer the delegate types would be nice although that has its problems.
This seems like a lot of (language and compiler) work and spec complexity for a small benefit.
Therefore I propose that following should be allowed:
//ommited arrows between parenthesis and return type defined as for last method in chain int Substract(int minuend)(int subtrahend) => minuend - subtrahend;
Personally I'd prefer something like this:
curried int Substract(int minuend, int subtrahend) => minuend - subtrahend;
The curried modifier would tell the compiler to generate code for a curried function.
This seems like a lot of (language and compiler) work and spec complexity for a small benefit.
I've learned to love currying in F# and other functional languages, and I think it would be great to have it in C#; so I disagree that it would have a small benefit.
But I agree that it would probably be difficult to make it fit in the language; the "obvious" approach of returning a delegate is too inefficient. How does F# handle this, anyway?
@thomaslevesque
In F# the callee is unaffected. let subtract minuend subtrahend = minuend - subtrahend; is still a single function that accepts two arguments. If the caller omits arguments then F# automatically emits a closure class which captures the specified arguments and has an Invoke method for the remaining arguments. For methods that originally accept more than two arguments you can continue to omit arguments and it chains those closure classes together.
This isn't really different than what I mentioned above, using lambdas and delegates for currying. F# uses a common set of generic base classes and a virtual invoke, C# would use a delegate invoke, but the two should be very similar in performance.
If C# were to implement automatic currying it would seem more appropriate to do what F# does and implement it at the caller. Provide a more succinct syntax to indicate that you're intentionally calling a method with fewer than required arguments (giant can of worms with overloads) and the compiler automatically wires up the closures/delegates/what-have-yous:
// Call Subtract but only pass minuend, compiler automatically emits
// closure class and assigns delegate
Func<int, int> curried = Subtract(10, ...);
int result = curried(5);
But is something like that really much more of an improvement over the current implementation?
Func<int, int> curried = (subtrahend) => Subtract(10, subtrahend);
int result = curried(5);
In F# the callee is unaffected.
let subtract minuend subtrahend = minuend - subtrahend;is still a single function that accepts two arguments. If the caller omits arguments then F# automatically emits a closure class which captures the specified arguments and has anInvokemethod for the remaining arguments. For methods that originally accept more than two arguments you can continue to omit arguments and it chains those closure classes together.
Ah, I see. I thought the currying was done at the callee, not the caller.
If C# were to implement automatic currying it would seem more appropriate to do what F# does and implement it at the caller
Yes, I guess that makes sense.
But is something like that really much more of an improvement over the current implementation?
Well I think it would make for more readable code. Basically it would just be shorthand for a lambda expression. I think it would be especially useful in combination with #5445:
Console.ReadLine()
|> Foo(..., 42)
|> Bar("blah", ...)
|> Baz(...);
@gafter
About small benefit.
AFAIK, functional composition is defined as f(g(x)), and in that definition, functions with more than one argument have no place. Currying is essential for function composition. Currying is decomposition into argument-function elements. Once one have basic elements, it becomes easy to compose them and decorate such a argument-function elements with ie. null-check, inject cross-cutting concerns ....
I'm not guru for functional programming, so please correct me if I'm wrong.
@thomaslevesque
Also note that in F# you can only curry with let-bound functions. Those functions also do not support overloading. F# type functions can be overloaded but do not support currying.
I think "closed because it's way too much work and would make C# much more complex" is a valid reason to close this request.
But the comment about "small benefit" is a bit strange. Currying and partial application works wonderful in other language and the theory is sound. Many people see it as an huge advantage in their daily work.
@HaloFour I think the fact that overloading in F# isn't allowed in those circumstances is more because of the complexities of type inference rather than partial application (although I might be wrong here).
Declaring the return type on functions/methods with curried parameters is very cumbersome. This is not a _small_ improvement as it alleviates a big pain for those of us who are comfortable with currying.