# C# Language Design Meeting for July 15th, 2024

## Agenda

- [`field` keyword](#field-keyword)
- [First-Class Spans Open Question](#first-class-spans-open-question)

## Quote of the Day

- "Obviously what the data means is that after we make `field` a keyword, usage of it as the name of a field will skyrocket, because that's what correlation means, right?"

## Discussion

### `field` keyword

Champion issue: https://github.com/dotnet/csharplang/issues/140  
Specification: https://github.com/dotnet/csharplang/blob/e44ebf7095e462ef5f9bbd869386a70cbd85e6d0/proposals/field-keyword.md#syntax-locations-for-keywords  
[Usage data](LDM-2024-07-15-usage-data.md)

We started today by looking at real world usage data for `field` and `value` as keywords, to allow us to evaluate how breaking of a change we are looking at. Our current strategy, making both `field` and `value`
keywords within property accessors, even when used as a nested expression, turns out to be extremely breaking. Internal repos show hundreds of errors, with more waiting further in the build process; the errors stopped
the build in root projects, which would have to be fixed up to then allow the build to progress further. Surprisingly (to the LDM, at least), `value` is actually _more_ breaking than `field` is, and by a pretty big
order of magnitude: our analyses find that, across various sources, `value` is used in a way that would break with this proposal 8-12 times more than `field` is. We're pretty concerned by the level of break here, even
with fixers, for a couple of reasons:

* A decent amount of the break was in generated (either through a separate tool or through a Roslyn source generator) code. Even with a fixer, that generated code would likely just be overwritten the next time the
  generator runs.
* Our original supposition that, because `value` already has special meaning in property bodies it would be fairly simple to unify with `field`, turns out to be completely false.

Given these issues, we have a few proposals on how to deal with this, scaling back the break to have less of an impact:

1. Accept the break, exactly as shown.
2. Scale back the keyword recognition to only consider _primary\_expressions_. For `value`, this fixes a lot of the errors; in Roslyn at least, it only results in a single build error, where `value` was used in a lambda
   inside the getter body.
3. 2, but separate out `value` entirely, and leave it alone. Just make the breaking change for `field`, and only in the _primary\_expression_ scenario.

To tackle this question, we started by looking at the two separate parts: should we scope the break down, and should we remove any breaks on `value`? Our first pass here was maximally breaking, as we wanted to see how
bad the reality actually would be. It turns out to be unacceptably breaking, so we are in strong agreement to scope down the break to just _primary\_expressions_. Next, we took a second look at `value`. While scoping
down the break would eliminate a very large percentage of the real-world breaks that we see here, it wouldn't eliminate them; Roslyn itself would break, just as the very first example. Our breaking change philosophy
was that any breaking changes need to be well-motivated, and looking at the actual data in comparison to our original suppositions, we now think that we don't have enough motivation to take a change to `value`. Even
though changing `value` would make it more consistent with `field`, we don't think we have enough justification to make it worth it. Therefore, we go with option 3.

#### Conclusion

`field` will only be recognized as a keyword when used as a _primary\_expression_ within an accessor body. Any changes to `value` will be removed from this proposal and its behavior will continue unaffected.

### First-Class Spans Open Question

Champion issue: https://github.com/dotnet/csharplang/issues/7905  
Specification: https://github.com/dotnet/csharplang/blob/4578db732a7d4aece52a07d1c822846b381f40b2/proposals/first-class-span-types.md#delegate-extension-receiver-break

Finally today, we took a look at a potential breaking change that could be caused first-class spans, and the proposed mitigation for it. This is a somewhat complicated case: the main issue is that because method group
resolution of an extension method called in extension form can actually apply a conversion to the receiver, that conversion could potentially be something that can't be boxed. This isn't really a problem today, because
the only conversions allowed here are identity, reference, or boxing conversions; these are all things that are already on the heap, so capturing the receiver into the method closure is perfectly fine. `Span`s, though,
cannot be captured into the method group closure, so if there is ever a method group converted to a delegate type, and it uses a span conversion on the receiver, that _will_ be an error. Since these conversions can be
prioritized, it means that currently valid code will become an error, particularly as the BCL adds new `Span`-taking overloads. Given the 100% error rate of the scenario, we are fine with adding a special rule to exclude
`Span` conversions when doing method group overload resolution on an extension method called in extension form.

#### Conclusion

Mitigation is approved.
