Skip to content
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 For Each statement with query comprehensions #104

Open
AnthonyDGreen opened this issue Jun 28, 2017 · 1 comment
Open

Extend For Each statement with query comprehensions #104

AnthonyDGreen opened this issue Jun 28, 2017 · 1 comment

Comments

@AnthonyDGreen
Copy link
Contributor

AnthonyDGreen commented Jun 28, 2017

Today most of VB is imperative and immediate but there's this whole separate world of declarative and deferred in queries. Queries don't execute immediately but many programs I see immediately realize the queries. Additionally combining For Each and a query creates this awkward syntax where you have to declare two different range variables - For Each outer In From inner In collection Where ....

Seems like it would be by syntactically elegant to extend For Each with query clauses:

For Each i In collection
    Where P(i)
    Distinct
    Order By i Descending

Next i

This syntax would help bridge the gap so to speak between the declarative and imperative worlds. #25 is the inverse of this and is also a really good idea. In fact you could combine the two to get the indexing of a For but with the variable capturing semantics of For Each:

Dim l = New List(Of Action)
For Each i In 0 To arr.Length - 1
    l.Add(Sub() DoSomething(arr(i))
Next

In a For loop executing any of the actions in l would always throw IndexOutOfRange exceptions since all lambdas would capture the last value of i (which is actually arr.Length not arr.Length - 1 because i is incremented before it's checked).

Last time we discussed this a big question was whether we should try to optimize the performance of this to be the equivalent of the user writing Continue statements and the like. While this could yield some performance benefits for LINQ-to-Objects scenarios I think the bigger performance concerns are LINQ-to-SQL/Entities where it's often best if as much of the query as possible executes remotely. We could use different code-gen strategies for IEnumerable vs IQueryable but I'm not sure it's really worth it.

@bandleader
Copy link

bandleader commented Apr 25, 2019

In another issue (here) I proposed some changes to query syntax, two of which would IMHO obviate the need for this proposal, by solving it in a more general way, that makes regular query syntax suitable for direct use in For Each statements. Quote:

  1. Instead of making us say From cust In, allow the variable name to be implicit -- maybe it like in Swift? e.g. From context.GetCustomers Where it.ID = id
    This is similar to property Set(value) where the identifier can be omitted (just Set) and defaults to value.
    This would only work for the vast majority of (my) queries; for the few nested queries and multi-Select queries that I have, I would still specify the variable name.

  2. As well, perhaps certain clauses (Where, Select, etc.) could turn the left-side expression into a query implicitly, with no From necessary. Then we could just do context.GetCustomers Where it.ID = id Select it.Avatar or similar. I think this was suggested in a separate issue, but becomes much more doable with implicit identifiers as above. I get why it' easier to force a keyword like From though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants