meetings/2023/LDM-2023-05-31.md
https://github.com/dotnet/csharplang/issues/5354
https://github.com/dotnet/csharplang/blob/main/meetings/working-groups/collection-literals/CL-LDM-2023-05-31.md
Today we took a look at what the collection literals working group has been iterating on, and tried to answer a few of their open questions. We started by looking over the list of preferable target-type construction patterns. The idea is to choose the most efficient construction pattern for a given collection literal, given that it has a specific type. Importantly, while this list talks about preferable construction patterns, it does not talk about overload resolution and what a most-specific type would be. Rather, the collection has already been typed by this point, and we are only trying to figure out how the collection will be constructed. There were a couple of concerns brought up during this that the working group will take back to consider:
foreach?IObservable sequence via a collection literal?We also discussed what the behavior for IEnumerable<T> would be: what type should we emit here? Should it be a guaranteed concrete type like List<T>, or something
else? Or something entirely hidden? The main concern here is around downcasting and observability of that. It's important to note that while some downcasting is not an
important scenario, some is entirely innocuous or even an important perf scenario: for example, LINQ will try to optimize known-length scenarios, which does involve
type testing and downcasts. Given that one of our focuses here is performance, we're not eager to have using collection literals introduce performance gotchas. However,
if we said List<T> is guaranteed, that also removes some ability to do performance work; for example, representing [] with Enumerable.Empty(), or caching for
IEnumerable<int>s composed of entirely const data. Given that, we don't think we want to commit to a single specific type. Instead, we want to work with the runtime
to make sure that we can eke out every scrap of performance. The working group will explore the space of using unspeakable and/or immutable collection types here.
Finally, we also looked at the Create method pattern proposed by the working group. We generally like the patterns, but think there potentially needs to be more.
For example, unknown-length collection construction does not work with the proposed patterns for ImmutableArray. We also considered whether these could just be static
methods on the type itself. The runtime is very against this, because these method patterns are somewhat unsafe for manual usage; for example, the ImmutableArray creation
method returns a mutable Span to the backing storage, which is super dangerous. We keep these types of APIs on specific Marshal types today (CollectionsMarshal,
for example), specifically to avoid them appearing in the standard surface area of the type, and we want to continue this pattern.
No conclusions for today, but plenty for the working group to take back and continue iterating on.