Skip to content

Latest commit

 

History

History
66 lines (46 loc) · 4.04 KB

LDM-2024-02-05.md

File metadata and controls

66 lines (46 loc) · 4.04 KB

C# Language Design Meeting for February 5th, 2024

Agenda

Quote of the Day

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

Discussion

First-class span types

#7905
#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 asyncified 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

#7913
#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:

// 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.