Back to Csharplang

C# Language Design Meeting for October 4th, 2023

meetings/2023/LDM-2023-10-04.md

latest3.9 KB
Original Source

C# Language Design Meeting for October 4th, 2023

Agenda

Quote of the Day

  • "PHONE ALERT TIME"

Discussion

Trimming and AOT

Today, we mostly listened to a presentation from the AOT lead and C# LDM emeritus Andy Gocke, which can be viewed here. We had a few small discussions during and after the presentation, which will be summarized here, but we'll let the slides speak for themselves for the majority of the content.

On alpha-renaming with attributes (slides 9 and 10), Andy pointed out that our closure renaming strategy today doesn't preserve attributes on type parameters, which makes it hard for AOT annotations to be preserved for lambda scenarios. We agreed that this is something that the compiler can likely address; how lambdas are lowered is not well-specified in the C# language, giving us the freedom to add more information if needed. However, this is a double-sided blade: because it's unspecified, it's not necessarily a good idea for an AOT framework to take advantage of a specific lowering strategy, even if more advantageous. We may want to think about whether we can specify enough to get AOT the information it needs without over-constraining the compiler.

The serialization models adopted by newer systems, particularly Rust and Swift, are attractive, and potentially doable in C# when we add extensions that can implement interfaces on unowned types. But there's a few potential problems we'll need to think about:

  1. Rust has an orphan rule for trait implementation, preventing users from implementing traits they don't own on types they don't own. They get away with the trait-based deserialization models in part due to the fact that they've been implementing serialization traits like this from the very beginning, so the whole ecosystem has effectively opted itself in. C# doesn't have that weight of momentum, so an orphan rule might kill any attempts by users to mix new serialization patterns in with existing code they don't own. However, we also don't think we need an orphan rule currently, as C# extensions will be actual named types, unlike in Rust. It is still something that needs to be investigated more in depth, however.
  2. The momentum argument also has impact on broader adoption: just like with nullable reference types, this would be a gradual adoption of a new serialization pattern across the entire ecosystem. Even if individual users can gracefully bring old, outdated patterns into new serialization patterns, it's going to be a long road before users wouldn't have to introduce lots of adapter interface extensions, and that's not including any frameworks that may simply decide to avoid the new patterns.

Regardless of these problems though, we think that the extensions working group needs to keep this use case in mind and prioritize it as a potential use case for the feature.

There's also some concern about compiler structures that aren't represented at runtime, and how AOT would be able to view these things. Currently, .NET AOT only works with C#, which is a detriment to the feature. Any further addition of language features that doesn't have real runtime representation makes it harder to work with from a cross-language perspective; for example, one possible implementation of reference could be simply treat it as object (or some other base type of the hierarchy) with some additional metadata to say which cases are possible. Would this then constrain how an AOT-compatible serialization framework needs to behave, and lock out other .NET languages besides C#? Similar issues exist for AOT based purely on source generating from C# syntax. These are hard questions that need to be dug more into, and we would like to do so.

There are no conclusions here today; serialization is an interesting scenario that we will continue to look at more.