# C# Language Design Meeting for June 5th, 2023

## Agenda

- [Collection literals](#collection-literals)

## Quote of the Day

Due to an unfortunate notekeeping snafu, there are no records of funny things said today. They did exist, but they are lost to the annals of time.

## Discussion

### Collection literals

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 [continued](LDM-2023-05-31.md#collection-literals) our review of the work the collection literals working group has been doing, this time
looking at dictionary creation patterns. We first thought about syntax, and the potential for ambiguous syntax. For example, this expresson would
be ambiguous:

```cs
Dictionary<K, V> d = [a ? [b] : c]; // [a ? ([b]) : c)] or [(a ? [b]) : c]?
```

There was also a question raised whether it might be useful to state from the literal itself whether it would be a dictionary or a sequence. For example,
`[..dictionary1, ..dictionary2]` might want to prefer combining into a new dictionary, not a sequence of elements. To try and address these cases, we
explored whether there was some alternative syntaxes that would mark the literal as a dictionary literal and force dictionary semantics.

* `[: a ? [b] : c]` - Leading `:`
* `[: a ? [b] : c :]` - Leading and trailing `:`
* `{ a ? [b] : c }` - Use `{}` for dictionary literals

None of these particularly resonated with the LDM. Further, no language that we can find that has dictionary literals differentiates them from collection
literals with an extra or different sigil, so there's no prior art to draw on. Given this, we don't think there needs to be a separate syntax for
dictionary literals, and `[..dictionary1, ..dictionary2]` will have sequence semantics unless target-typed to a dictionary type (including dictionary
interfaces such as `IDictionary<TKey, TValue>`), or unless the literal contains a `key : value` element.

Next, we thought about what semantics spreading dictionaries should have, when the literal will have dictionary semantics. For example, what would the
following code print?

```cs
using System;
using System.Collections.Generic;
Dictionary<int, int> dictionary1 = [1 : 2];
Dictionary<int, int> dictionary2 = [1 : 3];
M([..dictionary1, ..dictionary2]);

void M(Dictionary<int, int> d)
{ 
    foreach (var (k, v) in d) Console.WriteLine($"{k} {v}");
}
```

There are two possible behaviors: add behavior, where duplicate keys are error, or overwrite behavior, where the last instance of a key wins. There's two
competing schools of thought here. In favor of add behavior, most of our existing methods have this behavior. `CreateRange`, the `Dictionary` constructor,
collection initializers as they exist today, etc. However, `[a : b]` looks more like an indexer, which does have overwrite semantics today. There also some
concern that, as we borrow this syntax from other languages, deviating too much from their behavior will introduce a quirk that is more gotcha than it is
helpful. Ultimately, we think that we should prefer overwrite semantics for this scenario.

#### Conclusion

No special syntax for differentiating a dictionary literal beyond the `key : value` syntax for an individual element.  
Dictionary literals will use overwrite semantics, not add semantics.
