Replies: 38 comments
-
I think your proposal is impossible, since |
Beta Was this translation helpful? Give feedback.
-
Proposed here. Worth mentioning is that the |
Beta Was this translation helpful? Give feedback.
-
I (think) I'm in agreement with @YaakovDavis here, in that the placeholder character, var myValue = myList.where(x => x.age == 10 && x.lastName == "Smith");
// can be written as:
var myValue = myList.where(@.age == 10 && @.lastName == "Smith"); The use of |
Beta Was this translation helpful? Give feedback.
-
A |
Beta Was this translation helpful? Give feedback.
-
The verbatim specifier |
Beta Was this translation helpful? Give feedback.
-
I did not find the other proposal when i searched, but i am happy to hear that it is already in the works. We should probably move discussion over there. Regards to @Logerfo i am not an expert in language or compiler design. But i thought it would be easiest to "transpile" a shorthand lambda into the real one behind the curtains. Since |
Beta Was this translation helpful? Give feedback.
-
There's lots of proposals here, but only those "championed" by a member of the language team are even being talked about by that team, much less "already in the works". |
Beta Was this translation helpful? Give feedback.
-
(And maybe |
Beta Was this translation helpful? Give feedback.
-
My 2c: we could def add this to the language. I can even see the benefit to people. The question to me is: is the benefit worth it. Single-param lambdas are already pretty darn concise. They're easy to spot. They're universal. Do they really have enough 'overhead' to warrant an entirely new syntax to do the same thing over again. -- Finally, i'm not a huge fan of these approaches, because they seem to fall over with something like:
What does the second @ refer to? Is it a fresh lambda parameter for the lambda passed to 'Select'? Or is it the same @ as the outer @ used for the lambda passed to .SelectMany? Beyond that ambiguity, i think there is value in the parameter having a name (even if it's a single character). I may do something like:
The presence of these names, in context, makes it very clear what's going on. 's', 'c', and 'p' genuinely convey information and make these sorts of things much clearer to keep track of to me. |
Beta Was this translation helpful? Give feedback.
-
Surely the closest But I agree with your argument about the name. What might be neat is if parameter names could be exported from the lambda declaration. |
Beta Was this translation helpful? Give feedback.
-
C# has vigorously avoiding 'hiding' in expression scopes since our inception. It's super confusing. After all, if we have hiding, now i'm going to have to look at that code and realize 'oh, this inner @ is not the same as the outer @...' Ick. |
Beta Was this translation helpful? Give feedback.
-
(Warning: magic ahead, thinking out loud) Such as with public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) {...} Perhaps taking #470 to change the public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, TResult(TSource) selector) {...} and then we could tweak that feature syntax to allow argument names: public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, TResult(TSource src) selector) {...} Now with that, for this feature we could allow the lambda to be collapsed down to Since the identifier |
Beta Was this translation helpful? Give feedback.
-
I'm not sure it would, considering that both And nesting e.g. |
Beta Was this translation helpful? Give feedback.
-
I'm not sure any shorthand - The general use case as far as I can see is for short and simple expression, such as As soon as they get particularly complex such as nested selects etc., I'd be very much in favour of the compiler enforcing named lambda arguments, exactly as it does today. |
Beta Was this translation helpful? Give feedback.
-
Maybe we could allow lists.SelectMany(@.Select(@it.ToString())); // @it is lower scope, can be name anything
// also able to
lists.SelectMany(@list.Select(@.ToString())); // Anything allowed just error on collision |
Beta Was this translation helpful? Give feedback.
-
servers.Where(@.IsOnline); // vs
servers.Where(s => s.IsOnline);
This is directly comparable to: int x;
var result = int.TryParse(out x); //vs
var result = int.TryParse(out var x); I have never seen the value in As with so many of these little features, if you don't use them, you'll not see the benefit. |
Beta Was this translation helpful? Give feedback.
-
The latter is a case of being able to take something previously only possible in statement form, and make it possible in expression form. Not having an expression form for that case also has a cascading effect with other language features. That's not the same to me as taking something that is already a brief expression and just making it a few characters shorter.
Doesn't sound like that adds much then :) As already mentioned, i'm not opposed to this. I just think our time would be much better spent delivering improvements to other areas. Language design and implementation is zero sum. If we work on this, we must take away time and effort from other things. And i'd rather the effort we spend demonstrate more value than this. |
Beta Was this translation helpful? Give feedback.
-
That case in particular deeply worries me. That code is already legal today and already has clear meaning of getting the value of 'IsOnline', converting to a delegate if necessary, and passing to 'Where'. 'IsOnline' could already be a local function, method, local, parameter, field, property, etc., and lots of code today is already written this way. If we now overloaded this to implicitly mean that IsOnline not only bound to a value in scope, but it could also cause a lambda to be implicitly created, where it would somehow bind to that value in some way... that seems rife for confusion. For example, what if i have: servers.Where(MaxUpdateLength <= UptimeLength); Then how do you interpret this? Is it: servers.Where(s => s.MaxUpdateLength <= s.UptimeLength); // or
servers.Where(s => MaxUpdateLength <= s.UptimeLength); // or
servers.Where(s => s.MaxUpdateLength <= UptimeLength); // or
servers.Where(s => MaxUpdateLength <= UptimeLength); ? Does any identifier in the expression just become a potential point that you are implicitly binding to some unnamed lambda parameter? As with the 'do/apply' discussion, i think sigils or bindings are necessary in these types of cases. i.e. if i wanted to write something like that, then at the very least it would have to look like: servers.Where(s => MaxUpdateLength <= .UptimeLength); // note the naked dot This way you could easily see what was an implicit lambda parameter binding, and what was not. |
Beta Was this translation helpful? Give feedback.
-
Good points. Did you mean this? servers.Where(MaxUpdateLength <= .UptimeLength); // note the naked dot |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi I know that the value proposition here is seemingly small, but I would also ask you to consider its popularity: Kotlin and Swift already have this feature and exactly the same one was the #1 most requested feature for F# too (fsharp/fslang-suggestions#506). So maybe "It's not worth much but hey... give the people what they want?". I think most people's objection to lambdas is not how they read, but how you must type them. I know that the 'arrows' ('->' and '=>') can be tricky and / or slow to type. I know that's not really an argument, and you still wouldn't do it if it didn't feel right and was consistent and easy to understand. |
Beta Was this translation helpful? Give feedback.
-
This is a problem of the LDT's own making. By insisting that only the team is allowed to add language features, you have more requests than you can handle and so these simple "nice to have's" get sidelined. Whilst it obviously makes complete sense for the LDM to remain the design authority for language changes, it would make more sense for the team to focus on the "bigger picture", and to encourage the community to implement little changes like this. |
Beta Was this translation helpful? Give feedback.
-
@DavidArno |
Beta Was this translation helpful? Give feedback.
-
As I said above, I do not see the value in |
Beta Was this translation helpful? Give feedback.
-
@DavidArno I think I can empathize with the LDT here. Every single little change has to work with VS. Look at this commit: orthoxerox/roslyn@ba9497a. It adds Now let's say I am given the green light to go ahead and implement shorthand lambdas. I pick up my prototype and start extending it to support VS, IOperation and everything else. I have no idea which files I have to modify, so I spend some time reading the sources and finally prepare this PR. Now the LDT champion is placed in a position of a used car buyer. What I have written in the PR/ad is not nearly as important as what I haven't written there. Then now have to prepare a checklist of everything a language change must implement and compare it against my PR. It's probably feasible to prepare a checklist for a I don't say it's impossible, though. It probably requires a very painful rearrangement of the team, though. Effort must be allocated to developing checklists/guidelines for external contributors of features, effort must be allocated to reviewing the changes, etc. Internal language changes are planned, they have internal resources allocated and accountable. Now you are stuck with an external contributor that you have no leverage over. They do not have to follow the project plan, you cannot beat them with a stick like you can your own junior teammates 😈, they can go join ISIS, have a child or simply disappear. And Mads or Dustin have already showcased the first version of the feature on the blog or at some event, so you can't simply drop it. Now you have to pull people off other activities or work even more overtime yourself to finish it instead of that lousy external contributor. I am not saying this is exactly what will happen, of course, but this is a possibility that I guess no one is willing to ignore. Implementing this new policy will cost too much and won't really please anyone outside this repository. |
Beta Was this translation helpful? Give feedback.
-
When you put it like that... thanks for a very well thought out reply. I find myself agreeing more with you than with me. 😀 |
Beta Was this translation helpful? Give feedback.
-
@orthoxerox I think that even with the current system, a community-implemented feature is possible. I imagine a simplified version of the process would look something like this:
Though I don't know how much work would this actually save. And it would require both CM and LM to be willing to work closely together. But I think nothing in the current "champion" system stops this from happening, at least in theory. And I don't see why a rearrangement of the team would be necessary for this to happen either. |
Beta Was this translation helpful? Give feedback.
-
@svick the rearrangement was really about "encouraging the community to implement little changes like this". Your process looks like the one that is already in place, it's being "not too busy" that is one of the issues. Plus, it's not really encouraging anyone to implement a change, it's encouraging us to design a change. I don't think having a working implementation affects the chances of a proposal being championed. |
Beta Was this translation helpful? Give feedback.
-
This is not a little change. And people are definitely allowed to implement language changes. We will take them if
|
Beta Was this translation helpful? Give feedback.
-
I actually think it would. Part of our decision making is invariably a bang/buck assessment. Much of the time we have to estimate, and we may not always get that estimate right. Sometimes we've thought something was much more expensive than it actually turned out to be. For example, 'default interface members' was something i thought was going to be much more expensive from an implementation perspective than it's actually turned out to be. So if we have something that is only of small benefit, but would take a ton of work, we'll likely deprioritize that over something that is large benefit and a small amount of work. |
Beta Was this translation helpful? Give feedback.
-
On top of all the other reasons, But more seriously, I think it better converys what's going on here. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Adding the possibility to forgo typing a full lambda for simple expressions:
I have thought about this before i saw Kotlins syntax, but it is quite elegant and i think it would be nice syntaxical sugar for C# as well. Its a natural companion to Linq, but it may as well be used anywhere where lambdas can be used.
It should also support boolean expression
link to Kotlins spec for reference
Beta Was this translation helpful? Give feedback.
All reactions