Back to Csharplang

C# Language Design Meeting for October 19th, 2022

meetings/2022/LDM-2022-10-19.md

latest3.8 KB
Original Source

C# Language Design Meeting for October 19th, 2022

Agenda

Quote of the Day

  • "You should be able to criticize your own children." "All your children are terrible"

Discussion

Open questions in list patterns on IEnumerable

https://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.

Allowing patterns after slices

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.

Conclusion

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.

Allowing slicing to capture

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.

Conclusion

We'll revisit after the helper type is designed and we have a better idea on efficiency.