Replies: 70 comments 26 replies
-
Where does a shorthand lambda expression begin or end? |
Beta Was this translation helpful? Give feedback.
-
It would be a single expression. The sigil would effectively expand out to I'd be curious to hear other opinions and interpretations, but I'm personally not all that interested in another full-fledged syntax for lambdas. |
Beta Was this translation helpful? Give feedback.
-
As I said previously I like the idea but I think that the idea can be expanded to |
Beta Was this translation helpful? Give feedback.
-
@HaloFour Do you think this is necessary with method references in mind? I admit that they are more limited than something like this but I don't see how this is an improvement over proper lambdas. |
Beta Was this translation helpful? Give feedback.
-
@alrz I actually thought about this so thanks for bringing this up, I prefer this mostly because currently, we have to come up with letters that don't make sense or do but in many cases the variable isn't the subject and so using the position to access the object make more sense, at least to me and if it's an improvement over the current syntax then why not? |
Beta Was this translation helpful? Give feedback.
-
I'd evaluate the two independently. Method references can certainly make the expressions less verbose (depending on the syntax that might be adopted), but they can only represent a narrow set of those expressions. It's fine for simple |
Beta Was this translation helpful? Give feedback.
-
Underscore is still an identifier and yet, not a letter. And how
Mathematica has this but conciseness often wins out the readability in that context as there is an operator for most of functions. I think, if you have more than one or two parameters, you should be using meaningful names, no?
I'd prefer method references over lambda because (1) they avoid double invocation (2) they infer overloaded members (3) syntax is a nice-to-have after all. On the other hand, shorthand lambda (1) doesn't avoid double invocation because probably it's not a double invocation if you can't use method references already as you mentioned, (2) doesn't provide any advantage in terms of type inference compared to lambda expressions, they are practically the same, (3) the syntax is confusing. with any choice of token, honestly I can't imagine what language grammar you have in mind for this. The question is, why would you want to squeeze such an expression (that is admittedly not considered straightforward) to that form? I mean, if it's already in its simplest form, we probably shouldn't try to make it simpler.™ |
Beta Was this translation helpful? Give feedback.
-
I don't disagree. My statement is that method references can't fit in many of these scenarios. Java has both and I use method references where possible but I'm still using simple lambda expressions the vast majority of the time. |
Beta Was this translation helpful? Give feedback.
-
Well, I'm suggesting to use
Well, maybe, I mean sometimes you may want to do f(($1.A+ $2.B) + $3.C) and might not care so much about the parameters. The question is why we need to choose this feature over the other or vice-versa? p.s. I think I need to write a different proposal about it because it's slightly different than this one, @HaloFour what do you think? I mean mine would cover yours too. |
Beta Was this translation helpful? Give feedback.
-
My concern about such syntax is that it seems to largely intend to replace proper lambdas. I don't think that C# needs another full-fledged syntax for lambdas. It also seems like a nightmare to parse since there is no obvious place that the lambda begins. You could have a nested set of statements several levels deep and all of a sudden smack into a What does the following mean? I can think of at least two perfectly valid interpretations. f1(f2($1.A + $2.B) + $3.C) |
Beta Was this translation helpful? Give feedback.
-
Also two perfectly valid interpretations here: f1(f2(@.A + @.B) + @.C) |
Beta Was this translation helpful? Give feedback.
-
My proposal doesn't permit for the use of the sigil |
Beta Was this translation helpful? Give feedback.
-
So Even with that restriction the parsing will be rather convoluted. |
Beta Was this translation helpful? Give feedback.
-
Beginning of what? |
Beta Was this translation helpful? Give feedback.
-
Perhaps not, but if Func<Foo, string> func = @.Name; But I think that's fine. But the expression |
Beta Was this translation helpful? Give feedback.
-
Indeed, and I see zero value in having LINQ methods defining those names. |
Beta Was this translation helpful? Give feedback.
-
For what it's worth, here's what Elixir does for shorthand lambdas: https://hexdocs.pm/elixir/Kernel.SpecialForms.html#&/1-anonymous-functions In C#, perhaps that could look something like (In Elixir's case, nested shorthand lambdas are actually outright illegal, though I personally think it's unnecessary to go that far as long as you clearly define how parameter references work.) So the example in the original proposal would look like this: var query = db.Orders
.Where(@(@1.Value > 50.0m))
.Select(@(@1.Employee))
.OrderBy(@(@1.Name)); Admittedly not quite as short, but it's something to consider. |
Beta Was this translation helpful? Give feedback.
-
The latter is shorter. If you have spaces, you have:
Which is only one char longer. I don't see the benefit here. |
Beta Was this translation helpful? Give feedback.
-
Just to be clear, my previous comment was meant mainly as food for thought since multiple parameters and nesting (and the issues with those) were brought up here a while back; it wasn't meant as a counter-proposal in and of itself. In the interest of fairness, it's worth pointing out that the above shorthand form would be shorter (regardless of spacing) the more lambda parameters you have, where you're using those parameters in more elaborate expressions such as member access: x=>x.Value
@(@1.Value)
(x,y)=>x.Value+y.Value
@(@1.Value+@2.Value)
(x,y,z)=>x.Value+y.Value+z.Value
@(@1.Value+@2.Value+@3.Value) I imagine you could simultaneously allow the form originally proposed for the probably more common case of a single lambda parameter. There's arguably some precedent for that in how lambda expressions allow you to write There's also another thing to consider regarding multi-parameter lambdas. This could just be a 'me' issue, but sometimes when I'm typing out lambda expressions with multiple parameters, I might only realize halfway through writing the expression itself that I forgot to declare, say, a trailing parameter in the parameter list, so I have to move the cursor back and add in the missing parameter. The advantage of the shorthand syntax here is that if you've used, say, 2 parameters in the expression and you realize you need a 3rd, you just literally type |
Beta Was this translation helpful? Give feedback.
-
That seems to be almost no savings at all to me :) |
Beta Was this translation helpful? Give feedback.
-
In fact, the number of characters saved is exactly the number of parameters, at the cost of obfuscating the whole thing. When I see this
I can infer from the problem domain what Quoting the OP, I can rewrite the query as this:
And I don't need much insight to recognize that With positional parameters like
The first Code is read many many times more often than it is written; saving a few moments of the writers time once at the cost of spending a few moments of the readers time many many times seems a Faustian bargain. |
Beta Was this translation helpful? Give feedback.
-
@theunrepentantgeek Sure there are cases where this entire thing can be confusing and will require a little more time from the reader, but those cases are a small minority, and I like the idea of giving programmers the freedom and the responsibility of choosing the more fitting syntax. |
Beta Was this translation helpful? Give feedback.
-
while I'd love this feature, can I argue for a slightly different syntax? var query = db.Orders
.Where( .Value > 50.0m)
.Select( .Employee)
.OrderBy( .Name); I believe that having nothing in front of the "." makes it more intuitive, cleaner and easier to read? |
Beta Was this translation helpful? Give feedback.
-
In contrast to several of the suggestions here, I suggest that the var query = db.Orders
.Where(value.Cost > 50)
.Select(value.Employee)
.OrderBy(value.Name); While not as succinct as the |
Beta Was this translation helpful? Give feedback.
-
I had the same idea this morning, good to see others are having this idea, too, sad to see it got nowhere in 6 years and is seemingly dead for 1.5 years now? Sorry if this is unwanted bumping, but I was about to post a proposal, found a similar one in the search which had been redirected here, so I thought I'd voice my opinion here. My take on everything in this thread, sorted by my agreement in ascending order:
Historically, I found the best additions to the language to be those where I can remove code instead of replacing it, for example
I would be really great if I could write |
Beta Was this translation helpful? Give feedback.
-
Perhaps the argument's position could be expressed as (x,y,z) => x.Value + y.Value + z.Value Would become: {0}.Value + {1}.Value + {2}.Value of course one could also write {1}.Value + {0}.Value + {2}.Value and so on. Where the subscript must be an integer literal. |
Beta Was this translation helpful? Give feedback.
-
I am still weary about the whole "positional arguments" idea in general. I think it is quite rare that multiple arguments of a lambda are equal in meaning and commutable. More often, the different parameters are different things. For example when using LINQ, there are tons of opportunities for trivial lambdas (Where, Select, Any, All, First/Last/Single(OrDefault), etc.), but all of them also have a second overload that has two parameters, argument and index. Using {0} and {1} would give you an excuse to not name two things, but when they are not commutable, that's a bad thing IMO. Take this example: I think it would be better to be forced to write because it's easy to get confused with what {0} and {1} are. The whole point of arguing "the name should be omittable" is that it doesn't matter what name you use, because it is the only thing you use throughout the whole expression.
It's all equally clear to me.
I did a GitHub code search for Each result page has 20 entries, page 1 has 91 occurrences, page 2 has 60, page 3 has 195; makes 115 on average. 954k files means 47.7k pages, with ~100 occurrences per page that is about ~5M occurrences. ONLY for One thing I would like to mention though: let's not forget about the Note: I'm using
What examples from the search result would look like:
|
Beta Was this translation helpful? Give feedback.
-
Kotlin has the "it" keyword for this. And it uses a tricky braces syntax.
It would be great if the lambda has only 1 parameter to "it" / "this" implicitly:
and if you could declare any function with a single parameter as "infix" that allows operator-like syntax:
that allows you to omit the braces, you get a perfect DSL
just dreaming.... ref: https://kotlinlang.org/docs/scope-functions.html#functions |
Beta Was this translation helpful? Give feedback.
-
Well the objective is to eliminate the need to type the
and if the types of Perhaps also, the IDE could be enhanced to that hovering over |
Beta Was this translation helpful? Give feedback.
-
I get what you are saying - but being selfish here - I have no interest
whatsoever in the static thing - but use lambdas for almost everything. We
have very strict rules against using enums for anything [except like
calling winapi or something, where you are using someone else's code].
They lead to shotgun surgery and a proliferation of similar business rules
in different parts of the code. To me - you either don't have any
functionality hanging off the code, in which case an int would be fine -
for instance, if you are just passing a value through from a -> b -you are
far better off _not_ validating it - because then you have nothing to
maintain as you add stuff... and if you do have functionality hanging off
it - it's much better to use a serializer to pull it into a class - as
x.MyType.RenderAsImage() is soooo much better than a
function RenderAsImage( x, type ) that then does a switch on the types -
because in the former, to add a new type you only have to go to one place,
and you get a nice little compile assist of all the things you need to do -
whereas to code the latter - you'll probably never find all the cases where
you need to change - because for instance if there are five values but only
one of them does X - someone will probably just say if enumValue ==
theValue {...}.... which is something someone else is basically guaranteed
to miss when they add a new type that also has that behaviour.
Bottom line - whatever may be the norm , and whatever you think of the
above coding style - for us at least - any use of enums , or enum like
things, or most things like switches are strictly forbidden - in fact our
CI automatically fails anything with a cyclomatic complexity over 6 - which
instantly disqualifies most switches.
whereas lambdas and linq _abound_ - they appear everywhere
I'm not in any way trying to imagine I'm particularly representative of
what is out there - but I know for me at least - one feature I'd use daily
- and the other almost never.
|
Beta Was this translation helpful? Give feedback.
-
Copied from dotnet/roslyn#3561
This has come up a few times on CodePlex as well as here but I've not seen any formal proposal for it so I thought I'd post one just to track it and get some conversation going about it.
Many of the LINQ extension methods accept a single argument and return a value, most often the result of a simple expression stemming from that argument. In those simple cases the developer is still required to assign the parameter value to a name that cannot shadow a name used in the current scope and then immediately reference that name in the body of the closure.
I propose that a short-hand version of this common pattern where the value of the argument can be accessed through a specific sigil which must be referenced in the method body. The following uses the sigil
@
and is the same as the query above:Beta Was this translation helpful? Give feedback.
All reactions