-
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
Extend LINQ syntax #100
Comments
I really like this idea. Having to add the braces around the expression just to use the |
I agree that something like this would be very useful, but I don't like that you're proposing 4 different syntaxes for 4 different, but very similar, operations. What I would prefer is a single syntax that can be used to call any "finishing" method. VB.NET already has something like this, though I think its syntax is not ideal. |
I like the idea as well, but your first query (and most of the others) could be made simpler just writing like this: |
How about this? Aggregate item In collection
Where item.foo
Into Sum 😄 |
I like this idea a lot. |
@svick @DustinCampbell On the surface I do like the idea of a more generic syntax. If we consider "from" to be a multi-result reduce, a single-result reduce keyword may be well anchored. I worry that readability will be sacrificed as it breaks out of the current Plain English syntax. |
While we're at it, go ahead and add Distinct, Skip and Take. Just steal the code from the VB code base. |
@scalablecory: Agreed - this is a common thing to do and has always bothered me.So much, even, that I usually prefer the method-style syntax. On the other hand, I like how F# supports most LINQ operations quite nicely. The underlying mechanism (computation expressions) even allows for extensibility, so in F# you can easily define your own LINQ variant with all the operators you could ever want. That's probably not necessary for C# as long as the most common operators are supported out-of-the-box. |
Extend LINQ query syntax. From y In 1 To 10
From x In 10 To 1 Step -1 Syntax is close to what is already used by VB's for loop. It could be extended to include datetimes.
|
I think that this could be solved in a much more comprehensive way if C# allowed functions to be used as infix operators. Rather than extending the Linq syntax, C#'s syntax should be extended to take care of this without it being limited to just what the compiler team has the time to provide. |
@metatron-the-chronicler Do you have a specific proposal to offer? |
I actually wanted to make this a specific proposal but I haven't had the time to sit down and write it. At any rate I think it would be a good idea to simply allow functions to be used in the infix position. One might write something like from c in collection
select somefield ToList() the important thing is that ToList isn't some special syntax or expression. The compiler simply resolves to the method we all know and love based on the position (Though I can imagine that this might make parsing more complicated.) of ToList. Of course the same infix notation would ideally be available outside the context of a linq expression. The main benefit of allowing any function to be used in the infix position other than resolving this particular issue would be allowing for cleaner dsls. I've always found it to be a real shame that the query syntax wasn't implemented in this sort of way from the beginning. Though I suppose that doing so has other technical implications that I don't have the knowledge to dispute. |
@metatron-the-chronicler I'd be interested in seeing your proposal if you ever get around to it. |
@metatron-the-chronicler Maybe use attributes to define new linq keywords, so it doesn't have to break out of the Plain English look. |
What about:
Regarding the materialization clause, let's make it support any collection at all:
or:
or:
Maybe we can shortcut to
We need some way to make the compiler pick up the appropriate conversion. Maybe look for a constructor with an IEnumerable signature. Also, distinctness would be useful:
We need new methods in the BCL: DistinctBy, ExceptBy, IntersectBy, UnionBy, etc. Also, there is one helper method that comes up again and again on Stack Overflow: A method that can be used to partition a sequence into chunks of fixed length. This really should be added to the Enumerable class. I work a lot with data. Often even big, nasty ETL-style queries. These features would be extremely handy. Especially the materialization feature because you often need to materialize for debuggability. This forces an ugly syntax: You need to wrap the query in braces and add this dangling .ToList() at the end. Code formatters have trouble with that. |
You might want to propose that at the corefx repo, |
@GSPP I'm sure you meant it as example syntax, but var managers = from employee in employees
where employee.IsManager
select employee as Manager; |
Would Also, Entity Framework has |
@HaloFour true. Suggestions?
Maybe? Should be unambiguous. But the pattern doesn't work for Single etc. Probably this should not be based on type but on (extension) methods |
VB already supports the extra LINQ methods for <Extension>
Public Function PutMeInline(Of T)(
items as IEnumerable(Of T),
predicate As Function(Of T, bool)) As IEnumerable(Of T)
‘ Do something and yield results
End Function
Public Sub Main
Dim vals = {1, 2, 3}
Dim test =
From num In nums
PutMeInline num % 2 = 0
Select num
Distinct
ToListAsync
End Sub While this is an intriguing possibility, I’m sure the number of edge cases where the compiler would choke would make such a feature unwieldy. |
@GSPP Unfortunately from x in list
where x != null
select x into List
where List == null
select List I'm not sure what would work best. While 🍝 I might start by borrowing the existing LINQ clauses from VB.NET, from x in list
where x != null
then ToList(); // or apply, or terminate, or frob Or a way to mark extension methods as extending the LINQ syntax with a well defined behavior as to how parameters are treated? [LinqClause("tolist")]
public static List<T> ToList<T>(this IEnumerable<T> source) {
// redundant much?
return source.ToList();
}
from x in list
where x != null
tolist; |
I strongly vote for this one. I never use LINQ language queries and instead my coding guidelines is avoid using them and always use the extension methods directly, and that's because the ugly parentheses each query has to be wrapped in order to materialize it ( Until this issue is addressed, language-build-in LINQ is merely useless. I'd say the syntax should provide an operator that expects a shortcutted extension method available for
Asynchronous methods should also be supported:
Maybe there should be a verbose LINQ fashioned way to pass the arguments and completely avoid the use of parenthesis, but I personally don't see it as necessary. Anyway this feature is crucial for the completeness of the LINQ syntax. Some suggestions above proposed the |
If the compiler does not do it already would it be impossible to just require the type to be given to the identifier being assigned to and have the compiler do the conversion itself? |
There are so many opened issues all addressing the same idea. |
What would be a good addition, is to also have the item index as well. |
As @AdamSpeight2008 said, |
Adding terminating operators as keywords is probably not a good idea because there are too many of them. Single, SingleOrDefault, SingleAsync, SingleOrDefaultAsync, First, FirstOrDefault, FirstAsync, FirstOrDefaultAsync, Count, CountAsync, ToList, ToListAsync, ToDictionary, ToDictionaryAsync, ToArray, ToArrayAsync... where does it end? On the other hand I think it is a very good idea to support non-terminating operators specifically Skip, Take, Distinct. |
We'll keep this on the backlog as a reminder to consider something here. The best proposal I've seen was var x =
from item in collection
where item.foo
select item.bar
do Single(); (Or some other keyword). The idea is to add a query operator that is like a |
Would like to see if it can handle something like var x =
from item in collection
where item.foo
do ToDictionary(item.Key, item.Value); i.e. the range variable is available in the |
Grr... there was a minor typo.... I would say completely eliminate the variable declaration since I think the
|
@TonyValenti That would be a "LINQ statement" which is already proposed in #1938. |
No, that is not the goal of this proposal. The goal is to make queries that end with calls to methods like |
@TonyValenti the goal of this proposal is to make LINQ syntax align more with the standard feature set of LINQ methods, to reduce the need to fall back to that. It is not intended to replace loops. |
@MadsTorgersen I really like your proposal and it would be really nice if there was some flexibility on what follows the DO statement. For example:
|
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. |
This is largely continued in csharplang #101. |
I can't count the number of times I've written something like this:
Readability takes a nose dive, especially with complex or nested queries. There's a lot we can do to improve what is one of C#'s most powerful features. From low-hanging fruit that are compatible with existing infrastructure like ORMs:
To bits which are currently only usable by LINQ to Objects:
The text was updated successfully, but these errors were encountered: