meetings/2022/LDM-2022-10-19.md
IEnumerablehttps://github.com/dotnet/csharplang/issues/6574
https://github.com/dotnet/csharplang/pull/6365
Today, we took a look at the list patterns on IEnumerable proposal, and looked through a few open questions on the topic.
The first open question is whether we should allow patterns to follow a slice, such as enumerable is [1, 2, .., 3]. There's a few main concerns with allowing this: it will
significantly complicate the implementation of the emitted code, it could be a potential footgun for infinite IEnumerable scenarios, and, depending on implementation strategy,
it could actually perform worse than equivalent LINQ code would, as LINQ does typechecks for underlying types and uses indexing when possible. For the first point, we're not
overly concerned: the user would have to write equivalent code, and has more opportunity to introduce bugs when doing so, whereas a generalized and tested compiler solution is
likely more robust. The second problem we're also somewhat okay with: the footgun has existed since .NET 1.0, with IEnumerable and foreach. New places things can be enumerated
continue to have this footgun, but it's always the same one.
The last concern though, that using a list pattern might be less efficient than using LINQ, is a big one. We're okay with the infinite enumerable issue, but we don't want patterns
to be avoided because they're seen as the least-efficient way to implement a check. We should be able to optimize these checks for when the underlying IEnumerable doesn't need
to be fully enumerated to retrieve individual elements. We were planning on implementing a helper for doing these enumerations, and we should work with the BCL team to ensure that
it is as efficient as it can be. For example, LINQ has internal interfaces that it uses to back queries depending on whether the original enumerable was list-like, and it would be
good to have list patterns be able to take advantage of the same optimizations that Select or IndexOf can.
We're okay with restricting patterns after slices for now, but we should plan on having them eventually, and work with the BCL team to put a helper (type or set of methods) into the standard libraries that list patterns can use for being as efficient as possible without tying the language to implementation details of specific frameworks.
Finally, we looked briefly at whether or not a slice pattern on an IEnumerable should be able to capture the sliced section. One concern with this is that it would violate the
standard way we do slicing: a Slice method should return an instance of the same type it was called on. Slicing an array returns an array, slicing a Span returns a Span, etc. But
we couldn't do that here, as the underlying IEnumerable could be anything. It would also be weird if we allowed this when we don't allow slicing to capture for any list pattern:
we only allow slicing for types that are countable, indexable, and sliceable. We think that, after we work through a helper type to address the first point, we might be in a better
position to determine whether we should generally expand slicing support to all list patterns, or whether we don't think that should be generally supported in any non-sliceable
input context.
We'll revisit after the helper type is designed and we have a better idea on efficiency.