I propose to allow multiple variables in a query expression's let clause.
The specification would be changed to support this as follows:
A query expression with a
letclausefrom x in e let y = f, z = g, … …is translated into
from * in ( e ) . Select ( x => new { x , y = f, z = g, … } )
this would facilitate the use of out var arguments in query expressions with no additional machinery:
from x in e
select y = M(out var z0), z = z0
It may also have some synergy with tuples and pattern-matching.
/cc @jcouv @VSadov @AlekseyTs @MadsTorgersen
Please also consider the select+filter scenario of using pattern matching with LINQ which I think will become and incredibly common use case.
Would be nice if out variables in LINQ clauses could automatically be promoted to range variables. I know that would drastically change how the LINQ clauses are translated.
IEnumerable<string> words = ...;
var numeric = from word in words
where int.TryParse(word, out int number)
select number;
// translated into
var number = words.Select(word => {
int number;
bool success = int.TryParse(word, out number);
return (word, success, number);
})
.Where(tuple => tuple.Item2)
.Select(tuple => tuple.Item3);
I would like to point out that the proposed translation looks inconsistent with VB translation. In VB, comma inside Let clause is causes an extra Select call and all range variables declared in the Let clause prior to the comma are in scope after the comma. I.e. Let a = <expr1>, b = <expr2> is equivalent to Let a = <expr1> Let b = <expr2> and a is in scope in expr2.
We considered this yesterday in the LDM and we believe we are more likely to support
A query expression with a let clause
from x in e let (y, z) = e2 …is translated into
from * in ( e ) . Select ( x => new { x , y = (var (y, z) = e2).Item1, z = z } )
/cc @dotnet/ldm
Most helpful comment
Please also consider the select+filter scenario of using pattern matching with LINQ which I think will become and incredibly common use case.
Would be nice if
outvariables in LINQ clauses could automatically be promoted to range variables. I know that would drastically change how the LINQ clauses are translated.