Skip to content

Latest commit

 

History

History
45 lines (33 loc) · 2.9 KB

LDM-2023-04-26.md

File metadata and controls

45 lines (33 loc) · 2.9 KB

C# Language Design Meeting for April 26th, 2023

Agenda

Quote of the Day

  • "Do we need dragon warnings?"

Discussion

Collection literals

#5354
https://github.com/dotnet/csharplang/blob/760e4a772a06723ea6ab3edabe14029623302ea2/proposals/collection-literals.md

Today, we took a look at the current proposal for collection literals. The proposal is looking very good overall, but there are some open questions around how it should behave in some scenarios.

First, when the target-type of a collection literal is an IEnumerable<> of some kind, what type is emitted by the compiler? As written today, it's always List<>, but this has the potential to cause allocations when they aren't needed. It would be great, for example, if IEnumerable<string> e = []; could just be emitted as a call to Enumerable.Empty<string>(), avoiding the need for an allocation entirely. That can't happen today, though, as it's specified to be List<T>. This would also mean that we couldn't do optimizations for scenarios that pass a fixed list of constants to an IEnumerable<> function: the consumer could downcast to List<> and add to it. We think that, given that we are talking about IEnumerable<> and not some more specific type, it should be fine to not guarantee what underlying type we end up using; indeed, that's the entire point of taking an interface, rather than a concrete type.

Next, we looked at KVPs turning the collection literal into a Dictionary<> automatically. We have some immediate concerns with this provision: the user could just as easily want a List<KVP<K, V>> instead of Dictionary<K, V>. There are also concerning differences in behavior with how such a dictionary would be constructed: a Dictionary would be union semantics, where duplicate later keys can overwrite earlier keys (or, if specified slightly differently, it could throw instead of overwriting). A list would contain both duplicate keys, which is a large change in behavior with very little to indicate that the behavior has changed. A bit more digging pulled up the important scenario that this rule is trying to cover: [.. dict1, .. dict2] should result in a dictionary union of these two input dictionaries, or [.. dict1, key: value] should result in a copied dictionary, with key set to value. We therefore brainstormed an alternate rule, that would be useful not just for Dictionary<>, but also for any collection being splatted into another collection: the type of a splat should impact the natural type of a collection literal. This is a rough idea that the working group will need to further explore, but at first glance it seems both powerful and like it addresses the concerns that created this rule in the first place.

No conclusions were reached today, but the working group has more feedback to go iterate on and come back to LDM with.