[Proposal] Introduce a target type for foreach statement expressions #9562
Unanswered
thinker227
asked this question in
Language Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Proposal
Currently, the following code does not compile due to the collection expression lacking a target type:
It would make a lot of sense for there to be a target type in this situation, since foreach statements naturally expect an iterable type. This would allow a short and concise syntax for applying a foreach loop to either a collection of constant values (as shown above) or an aggregate of collections (eg.
foreach (var x in [..xs, ..ys])
, and would feel like a natural fit for collection expressions which would make them ever so slightly more ergonomic.Proposed target type
I propose that the target type for the expression within foreach statements should be
IEnumerable<T>
. The type synthesized for the collection expression could be the same as used by the compiler elsewhere where a collection expression is used with the target type ofIEnumerable<T>
. As opposed to the concerns around natural types for collection expression (eg.var xs = [1, 2, 3];
), as far as I'm aware there are no such concerns here since the collection itself cannot be accessed and therefore does not require a concrete type outside of what is required by the foreach statement. In fact, even though I'm proposing the target type to beIEnumerable<T>
, it doesn't necessarily have to be, it could just be some compiler-synthesized type which implements the iterator pattern required by foreach (and truthfully this would probably be better/simpler).Optimization
In the same manner as the compiler synthesizing types for collection expressions targeting interfaces, if aggressive optimization is desired, perhaps the foreach could be rewritten or elided entirely. For instance, if the collection expression has a fixed amount of elements, the foreach could be rewritten into the equivalent of a for loop. Similarly, if the collection expression consists of multiple spreads (
..
, unsure of the correct term), it could be rewritten into one foreach loop for each of the collections. This would perhaps entirely remove the need for any kind of allocation or boxing or need to use the iterator pattern in the first place, essentially turning the loop body into a local function called multiple times with a set of known elements.My point is that there could be a lot of optimization opportunities here, if desired.
Possible issues and concerns
The obvious concern is whether this would be useful enough for most users to warrant implementing, which I unfortunately cannot comment on due to lacking usage statistics or similar knowledge. If enough interest is shown, the LDM would probably have a great deal to say about it.
The second and perhaps more prevalent concern would be around type inference in the case that
var
is used in place of the iteration variable type. I do not have extensive knowledge of the type inference rules so I can't give confident claims of how easy any implementation would be, but I would assume simple cases such asforeach (var x in [1, 2, 3])
to be relatively unambiguous. More complex cases such as when the elements of the collection have varying types could perhaps use the same inference rules used for inferring generic type arguments. This would still not be a bullet-proof solution, but it would likely work for a majority of cases. This of course also relates to existing issues around improving type inference in general.Beta Was this translation helpful? Give feedback.
All reactions