# C# Language Design Meeting for February 5th, 2024

## Agenda

- [First-class span types](#first-class-span-types)
- [Collection expressions: inline collections](#collection-expressions-inline-collections)

## Quote of the Day

- "Did I spell legite correctly? My Memory<spelling> isn't that great" "No, it's legit. Trailing e would make it like vegemite."

## Discussion

### First-class span types

https://github.com/dotnet/csharplang/issues/7905  
https://github.com/dotnet/csharplang/pull/7904

We started today by looking over a new proposal aimed at addressing a few pain points with `Span` and `ReadOnlySpan` that the language and library authors
have encountered since their introduction. These are areas that arrays work well in, but `Span` and `ReadOnlySpan` do not. To that end, we reviewed a
proposal for treating these types more specially in the language, much as we do for array types. We had a few thoughts on specific parts of the proposal:

* Even though `ReadOnlySpan<T>` exposes the `T` by `ref`, it's always a `readonly ref`, so we're fine to treat it as if it's covariant. If the `T` was just
  by `ref`, it wouldn't be safe.
* We're fine with `is` not working covariantly. This is the same thing as `int` to `long` conversions: C# can do it, but the runtime doesn't know about the
  conversion in type checking.
* We thought about whether this should extend to `Memory<T>`, but are wary of it. `Memory<T>` does not have an implicit conversion to `Span<T>`/`ReadOnlySpan<T>`
  because, depending on the backing storage, it can have a cost to convert, and we'd be worried about suddenly creating such conversions in the language.
    * At the same time, though, we are also sympathetic to the concern that, if a code path needs to be `async`ified and converted to `Memory<T>`, that may
      necessitate more changes to allow what works for `Span<T>` to work in the `async` world.
* We may need to keep special cases for betterness to keep `ReadOnlySpan<T>` better than `Span<T>`; in the psuedo type hierarchy, `Span<T>` is better than
  `ReadOnlySpan<T>`, because it is more specific. However, this is not what we want overload resolution to choose, since `Span<T>` offers worse performance
  in most cases.

Overall, we like the direction of this proposal, and want to proceed with it. We'll answer open questions as implementation progresses.

#### Conclusion

Proposal is accepted.

### Collection expressions: inline collections

https://github.com/dotnet/csharplang/issues/7913  
https://github.com/dotnet/csharplang/pull/7864

Next, we looked at one of the collection expression topics we want to handle in C# 13, inline collection expression usage. These are scenarios where a collection
expression is immediately used and never observed outside an expression, usually to handle some kind of conditional addition to a collection, or to enumerate
in a `foreach`. The main question here is whether we should rely purely on natural typing for these scenarios, or whether target element typing should flow in
somehow. For example:

```cs
// If `byte` doesn't flow into the conditional as an element type, the natural element type will be `int`, and the conversion will fail
byte[] x = [1, .. b ? [2] : []];

// If `bool?` doesn't flow into the iteration expression, there will be a compile error because no natural type can be found
foreach (bool? b in [true, false, null]) {}
```

We do have some disagreements on how exactly that information would flow into the expression to give it a final type: do we have to have some stopgap solution
until we have a natural type concept, or can we just integrate with that? We're generally in agreement that these examples should be able to compile, meaning
that we are generally in favor of flowing in an element type in some fashion. With this direction, we think the working group can take the lead on integrating
with natural typing work and then propose the final approach to LDM (or propose that it doesn't integrate with specific reasoning for why it shouldn't).

#### Conclusion

We are in favor of target element typing flowing into collection expressions.
