meetings/2021/LDM-2021-04-07.md
MVP-nominated session agenda
Today we held a more informal LDM session with Microsoft MVPs, where we selected an agenda from their suggestions and a brief discussion on our thoughts around the topic, as well as getting their impressions and potential concerns on the topic.
One thing we heard today was that there are definite use cases for this feature, not just in interfaces, but also in class types. This will particularly help with abstracting construction scenarios. There are also likely cases in Objective-C and Swift interop code that will be made simpler with this feature, which we hadn't yet looked at as a possible application for this. We also briefly discussed the issue of multiple inheritance with default implementations of abstract methods, but no new problems arise from abstract statics that did not already exist with default implementations of instance interface members.
A common complaint in C# is when users need to include literals from other languages such as XML or JSON, or even C# itself (particularly evident in source generators). While we aren't looking for language-specific literal types, we are looking at a more general "raw string" proposal that will allow more customization of escapes inside the string, which will address the problems around copying and pasting text that includes quote marks in it.
Some questions were raised on why we haven't updated expression trees since initial release. Our concerns here are around expression tree consumers: any update we make to start including new things in the tree will likely break consumers of expression trees. This starts to get particularly gnarly when we consider libraries that users want to ship and support on older target frameworks, or when newer code wants to depend on older code that hasn't been updated for handling of new expression tree constructs. We need a good proposal around how to handle the guardrails in these tricky scenarios to move this forward, and we don't have one yet.
Questions here centered around 2 points. First was ease of use, such as being able to define a source generator in the same project that consumes it. We are currently focussed on the V2 of the source generator API, but after that is shipped we'll be turning to focus on more general ergonomics, and this will be one of the areas we'll investigate. There are some particularly hard questions around running a source generator when the project doesn't compile.
The second point is in source replacement. We are very unsure about this feature: in particular, the IDE experience isn't great. We've already received occasional bugs from users about IDE experiences with existing code-rewriting solutions such as Fody (such as debuggers appearing to misbehave), and we have additional concerns about the perf implications of such generators.
A number of scenarios would like lambdas to be more efficient. In particular, some applications of LINQ should be able to be cost-free, as the results are immediately used and don't need to allocate closures. However, we don't have the language facilities to do this today. If we add the ability for ref structs to implement interfaces and be used in generics, we could get this feature, but usage would be extremely unergonomic due to the inability to infer generics parameters for some of the cases involved. To really make a feature like this usable, we would also want associated/existential types to remove those uninferrable generic parameters.
This has been one of the ultimate examples of bikeshedding. We have an obvious syntax in readonly, but we are concerned that the effort
the user would put into putting readonly everywhere doesn't match the actual benefit they would derive from doing so. C#'s past a
mutable-first language is definitely a liability with this issue.
We revisited why we are looking at this feature as C# syntax, and not as a project file switch. There are 2 reasons for this: we think we can do a better tooling experience in source, and we think that it will compose well with using aliases to enable other much-requested features. It does make multiple-project aliases a bit more difficult, as the user will have to include the file from multiple projects, but we think it's a worthwhile tradeoff. We also looked at global usings nested inside a namespace. We're concerned about the user experience for such constructs, and that the use case isn't there currently. If we see a need for this in the future, we can look at it then.
While this is an interesting idea, the compiler support here is somewhat scary. Additionally, VB.NET and C# have a number of very subtle differences that could very easily lead to developer confusion. Overall, we're not pursuing this area.
While we wanted to look at discriminated unions for C# 10, we don't think we're going to be able to. In particular, there are some big questions
left around type inference to be solved. Option<T>.None won't be particularly ergonomic until we do so. We also took a brief survey to see
what the MVPs are looking to get out of the feature: