-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Propose compiler support for currying/partial application of delegates/methods. #15575
Comments
This sounds like it would depend on #3990. Otherwise you'd need to define those intermediate delegate types. The compiler doesn't currently have any special awareness of the The CLR doesn't currently support signature equivalence for delegate types either. "Converting" from Somewhat related: #4534 |
As @HaloFour mentions, the CLR doesn't allow conversion between different delegates with identical signatures. However, support around this could be added via the compiler in a trivial fashion (admittedly still needing that wrapping to occur). For example, when encountering a new non-void delegate type: public delegate int MyDelegate(int p1, int p2, int p3); The compiler could automatically emit a new static class with extension methods: public static MyDelegateExtensions
{
public static Func<int, int, int, int> ToFunc(this MyDelegate del) =>
new Func<int, int, int, int>(del);
public static MyDelegate ToMyDelegate(this Func<int, int, int, int> func) =>
new MyDelegate(func);
public static Func<int, Func<int, Func<int, int>>> Curry(this MyDelegate del) =>
(x) => (y) => (z) => del(x, y, z);
public static Func<int, Func<int, int, int>> Partial(this MyDelegate del) =>
(x) => (y, z) => del(x, y, z);
} Likewise, the same could be done for Thus for any delegate defined, conversions between in and And even if this were something that the compiler team wouldn't want to implement, if Source Generators get implemented, and implemented well (ie, not just for partial classes), then this is something that could very easily be added to the language using a generator that detected delegates and emitted that static class in a new "paired" file. |
Source generators don't require partial classes. That's only necessary if the generated source is going to emit a partial class in order to add/replace existing members. And you only cared about the |
I may be misunderstanding how Source Generators work - but if they're only being applied at compile time, then how is that going to affect the developer experience? When using the proposed currying & partial application, any corresponding intellisense options (including documentation from the originating function) should be available to the developer as they type. It's of limited use to developers if they can only use it in a similar fashion to T4. |
If you have the stamina, read through #5561 (especially toward the end). The language team's position (or at least @CyrusNajmabadi's position) is that it only makes sense for Microsoft to do Source Generators if they are built into the entire "IDE experience" (my words). In other words, those generators would have to work with the IDE's intellisense, error detection etc etc. Assuming they happen (as it sounds a lot of work & other stuff, eg full-blown pattern matching ought to take priority), then my example generator would be sitting there in the background generating those extension methods as you type, such that eg auto-complete knows about them. |
Closing this out. We're doing all language design now at dotnet/csharplang. If you're still interested in this idea let us know and we can migrate this over to a discussion in that repo. Thanks! |
Currying or partial application (PA) in C# can be achieved quite handily with a few extension methods, such as:
However, this is only usable where the generic types of the parameters and return values are exposed via the set of Func or Action delegates. If I have a delegate with the equivalent signature, I can't apply either technique.
It would be useful to be able to convert a delegate/method to it's equivalent signature as a Func/Action to be able to apply currying or PA. Ideally, C# would expose some syntax for them and the compiler would handle the creation of corresponding closures. e.g.
Bonus points for making it possible for IDEs to display the documentation of the originating delegate/method for the curried and partially applied instances.
I realize this feature is probably not high on the priority list, but there's been a lot of syntactical sugar added to C# lately, so I thought I'd ask. Maybe this is low hanging fruit.
It would open up some pretty useful functional approaches to coding in C#.
The text was updated successfully, but these errors were encountered: