# C# Language Design Meeting for October 11th, 2023

## Agenda

- [C# spec update](#c-spec-update)
- [Collection expressions](#collection-expressions)

## Quote(s) of the Day

- "I think that's a great segue, because \<redacted's\> voice has always reminded me of cardamom syrup." \<redacted\>: "_what_?"
- "The chat has descended into madness" "We're solving \<redacted's\> coffee problem" "\<redacted\> and \<redacted\> are about to open a Starbucks franchise in the C# team room"

## Discussion

### C# spec update

[C# 7 specification update](LDM-2023-10-11-specification-update.md)

The specification effort for C# 7.3 has completed, and the formal spec has been submitted to ECMA for ratification. Following this effort, the committee will be moving onto
C# 8, but there were a few questions to clarify with the LDM before getting started on that:

1. The committee renamed `safe-to-escape` and `ref-safe-to-escape` in the specification for clarity. Should we update the existing documents with this info, and if so, should
   we update the C# 7 speclets as well as the C# 8+ speclets?
    * After some deliberation, we think the right answer is to update the C# 8+ speclets with this info. The C# 7 speclets are now effectively obsolete; the features have been
      integrated into the real specification, and we don't link to them from the documentation anymore. We'll put a note in the root of the C# 7 speclet folder on csharplang
      that the speclets there are outdated, and that should be all we need to do. For the C# 8+ speclets that refer to the outdated names, these are still active documents, so
      we'll update them with the new names. We'll also include a note that the term was renamed for past readers who look at the document again. We don't plan on updating issues
      or notes with these new terms.
2. There are a few outdated branches on csharplang from before the ECMA committee moved to the csharpstandard repo. These need to be cleaned up.
3. Finally, we currently have docs issues on the C# speclets opened on the dotnet/docs repo. This usually means that we go through a multi-level ping before getting to the right
   person to answer the question. The content itself is hosted from the csharplang repo, so should we move the issues to be filed on csharplang repo as well?
    * We think we should do this. The volume of issues is pretty low, and it will remove a level of indirection for getting questions answered or docs fixed.

### Collection expressions

https://github.com/dotnet/csharplang/issues/5354  
https://github.com/dotnet/roslyn/issues/70318

Finally today, we considered whether collection expressions should prefer `ReadOnlySpan` over `Span` for APIs that are overloaded on these two types. This isn't a super common
case, but it can happen. Some examples include extension methods (these may be overloaded because extensions on `ReadOnlySpan` do not appear on `Span` receivers), or
`ImmutableArray.Create`. Our existing rules prefer `Span` here, because it can be converted to `ReadOnlySpan`, and is thus the "more specific" type. And, at least conceptually,
it's possible that `Span` is the better type in some scenarios: perhaps the API that's being called can be more efficient if it can mutate the input buffer. However, looking at
the existing ecosystem, this isn't the case; the cases we see would indeed prefer an allocation-less `ReadOnlySpan` if at all possible, rather than `Span`. We also think that we
have more leeway with collection expressions to choose the better type if possible; unlike, say, `new[] { 1, 2, 3 }`, we're not explicitly allocating new space with `[1, 2, 3]`.
We also considered what exact wording to use here; we ended up at very similar wording to how we specified the `Span` vs array type betterness, requiring an implicit conversion
between the element types to avoid the same problems we discussed [here](LDM-2023-09-20.md#overload-resolution-fallbacks).

#### Conclusion

`ReadOnlySpan<T1>` will be preferred over `Span<T2>` in overload resolution for a collection expression parameter when `T1` is implicitly convertible to `T2`.
