# C# Language Design Meeting for July 17th, 2023

## Agenda

- [Compiler Check-in](#compiler-check-in)
- [`readonly` parameters](#readonly-parameters)

## Quote of the Day

- "Entra (ɛntrə) or Entra (ɑːntrə)?" "Depends on where you're from" "I can azure you there will be no questions about pronunciation"

## Discussion

### Compiler Check-in

https://github.com/dotnet/roslyn/blob/673caaadc9780ad19d2295874607b635b017e0e3/docs/Language%20Feature%20Status.md

To start, we wanted to check in with the features that the compiler is currently working on, when they're going to be shipping, and
whether we need to rename any of them.

* Inline Arrays
    * We're good with the name of this one.
    * Shipping in C# 12
* nameof accessing instance members
    * We're calling this `enhanced nameof` to a broader audience, but this is fine for a status page and for more specific documentation.
    * Shipping in C# 12
* Primary Constructors
    * We have existing name precedence from records and from other languages, so we're good with this name.
    * Will be shipping in C# 12.
* Semi-auto props
    * Unfortunately, this one won't make C# 12.
    * Name isn't great. Many of us think it should have `field` in it somewhere, as that's what we've been internally calling it.
    * `field access for auto properties` is the proposal.
* `params Span`
    * This won't make 12, as it needs inline arrays to be implemented.
    * There are also potential issues around https://github.com/dotnet/csharplang/issues/7276 when adding new overloads that take `params Span<T>`
      that we'll need to address.
    * We're ok with the name of the feature at least.
* lambda default parameters
    * We're fine with this name.
    * Will be shipping in C# 12.
* Default in deconstruction
    * Fine with the name, there are still some LDM questions to answer.
    * Not shipping in C# 12.
* Collection literals
    * We're worried that using the word literal here conveys the wrong first impression. Literals in C# are immutable (`unsafe` string buffer manipulation
      nonwithstanding), while these expressions are not; they give you a collection that is as mutable as the target type allows for. We suggested a few
      alternatives, and settled on Collection Expressions.
    * Will be shipping in C# 12.
* Roles/extensions
    * The name in this file needs to be renamed to catch up to the current feature name `extensions`, but as this will only be in preview for C# 12 we
      aren't tied to the name yet.
    * In preview for C# 12.
* Interceptors
    * The name is the least controversial thing about this feature.
    * In preview for the C# 12 compiler.
* ref readonly parameters
    * Name works for the specific feature, though some of the broad docs might put it in a general ref enhancements bucket.
    * Will be shipping in C# 12.

### `readonly` parameters

https://github.com/dotnet/csharplang/issues/188  
https://github.com/dotnet/csharplang/blob/ee2c62fbacf3e84457198624c71abdca326c2cd8/proposals/readonly-parameters.md

Finally today, we looked at a proposal for `readonly` parameters. This is a long-requested and highly-upvoted issue on the csharplang repo, but various
members of the LDM have pushed back on it as not delivering enough value for the level of change it would bring. In particular, much of the LDM is
concerned that adding `readonly` to parameters and locals changes what default "good C#" looks like. This is similar to initial designs of the nullable
reference type feature, where we indicated non-nullability with a `!`, instead of indicating nullability with a `?`; for that feature, we felt that the
ideal version of code requiring `!` modifiers everywhere was surprising and not where we wanted the language to be in 5 years. In the case of nullable,
the scope of the problem being addressed was big enough that we felt comfortable adding an entire new dialect (via the `#nullable` directives) to move
the language over to the new defaults. For `readonly` on parameters and locals, we feel similarly that we don't want the default of the language to be
long modifiers on all parameters and locals, but are unconvinced that the scale of the problem is large enough to warrant language dialects like we did
for nullable, given the narrow scope of locals and parameters.

This calculus changes in the face of primary constructor parameters. These can get captured into the state of an entire type, potentially spread across
multiple partial parts, and the safety benefits are therefore more substantial. We've received significant feedback, both internally and externally, that
capturing primary constructor parameters is being considered "off limits" until they can be marked `readonly`. Given the previous concerns about the look
of "good" C#, we are very inclined to restrict this to just primary constructors, at least initially, though the proposal does somewhat dictate the course
of what both locals and parameters would look like if we were to do so. There's also an interesting question on `readonly struct`s, as we make the
all the parameters implicitly `readonly` today; we require `readonly` on all fields in such a struct, do we need to require it on all parameters as well?

Another question raised was whether we should re-examine the default mutability of primary constructor parameters. Perhaps the least surprising thing is
to have the parameters as immutable, and require explicit field declaration when mutability is desired. There's some conflict here: how does that interact
with `record struct`s, where the generated properties are mutable by default? And will that impact future designs in this space?

Finally, we want to make sure that we don't lock ourselves out of any future feature work here. There's some feeling in the LDM that we'll eventually
allow ways of declaring that a primary constructor parameter is a part of the class state, either as a field or as a property. We need to more completely
explore this space and make sure that allowing `readonly` on a primary constructor parameter does not lock us out of such a future feature.

#### Conclusion

Enough interest to look at this in more depth, but in a more restricted form than initially proposed.
