-
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
Partial function application and function chaining #3171
Comments
I think that you're still going to run into the problem of lack of inference of the return type. The issue isn't figuring out the signature of the function, it's figuring out which compatible delegate type to use. Even if it could figure that out to some arbitrary delegate since delegates don't have structural equivalence if you then have to pass that delegate to a method that accepts a different type of delegate with the same signature it will cause an additional delegate invocation adding quite a bit of overhead. As for the functional pattern itself, I make use of partial application and currying in numerous places in my code base and I'm not that sure that this syntax is that much clearer. Less verbose, certainly. To make sure that I'm reading it right, the following two are effectively equivalent, right?
|
No, they are not exactly equal, four and hahahaha are an int and a string, respectively. I agree that lack of delegate type inference and structural equality is a hurdle for the implementation of this feature, but F# compiler has seemingly managed to jump over it. |
Actually, I've made a mistake, the line with Fixed the original post. |
Hm, so it's really just an alternate syntax for method invocation? That doesn't seem particularly useful. Granted, sometimes nested invocations can be a little inside-out, but that's the common paradigm with structured and object-oriented languages. What reason would there be to include this additional syntax other than to make C# smell more like F# or Scala or whatever? |
It's more suitable when your program is better represented as a chain of functions. Yes, extension methods serve the same purpose (by replacing nested calls with a chain of methods), but |
aka, it's more suitable for functional languages. C# is not one of those. As you demonstrated it already doesn't work with |
|
I would agree that inference of delegate types for lambda expressions would be quite useful. The issue, as mentioned above, being that there is not one delegate type for a given signature so the compiler has no idea what type to make the variable. If the compiler guessed (or just used Although, I also think that anyone learning to use C# really should learn about those particular delegate types as well as how delegates work in general, whether or not they intend to use them in functional programming patterns. |
I would be quite happy with partial functions been a syntax sugar on top of Func and Action . |
Even fluent-style LINQ will benefit from this proposal. Instead of writing
you will be able to write
or whatever sigil we will end up with. |
Interesting factoid. We actually had a syntax similar to this for lambda expressions before deciding on the current fat-arrow form. |
We are now taking language feature discussion on https://github.com/dotnet/csharplang for C# specific issues, https://github.com/dotnet/vblang for VB-specific features, and https://github.com/dotnet/csharplang for features that affect both languages. |
Let's say I have a (deliberately useless) function:
I can use it to create a function that adds 5:
I cannot use type inference or define it inline:
However, what I would really want is a way to create chainable inline definitions:
Unfortunately, underscore has been a valid identifier since C# 1.0, so we cannot use this wonderful syntax. Pattern matching is probably going to use
*
, but this will conflict with operator-bodied expressions like_ + "!"
. Large non-operator glyphs are$
,@
and#
. Let's see which one looks the best:I cannot decide which one looks better. I am also not sure if methods should be callable using this syntax (
list |> _.Count |> _.ToString
) looks ugly, but perhaps this is inevitable if we allow chaining arbitrary expressions.Of course, if the function being invoked is actually an expression, it should be automatically reduced if possible to a more simple expression.
The text was updated successfully, but these errors were encountered: