# C# Language Design Meeting for May 9th, 2022

## Agenda

1. [Numeric IntPtr](#numeric-intptr)
2. [Ref readonly parameters](#ref-readonly-parameters)

## Quote of the Day

- "Not all Unsafe is created equal"

## Discussion

### Numeric IntPtr

https://github.com/dotnet/csharplang/issues/6065

This C# change is mostly a reaction to a change in the BCL's thinking around `IntPtr`, and how generic math will apply to it. During the design of
`nint`, we wanted to keep `nint` and `IntPtr` as distinct as possible, as the intent was not to enable general math on `IntPtr`s. However, as the
BCL has rationalized their generic math designs, they've decided that the easiest way forward will be to remove this distinction, and enable
generic math on `IntPtr`. We therefore want to update C# to similarly remove the distinction, and regard `nint` as simple alias for `IntPtr` (and
`nuint` a simple alias for `UIntPtr`) to keep the language and runtime in sync.

#### Conclusion

Accepted.

### Ref readonly parameters

https://github.com/dotnet/csharplang/issues/6010

We wanted to revisit the decision we made [last time](LDM-2022-04-25.md#ref-readonly-method-parameters), as further discussion after the meeting
revealed that we had conflated a few features in the decision, and we wanted to break them out and be sure that we are comfortable with feature.
In particular, we did not explore the analyzer route enough, as further investigation revealed that, after the `in`/`ref` mismatch was dealt with,
nothing prevented using an analyzer to prevent rvalues being passed to `in` parameters. There are 3 main components, therefore, that this proposal
seeks to address:

1. There is no way to move an existing API from `ref` to `in` without a source-breaking change. We addressed this issue by allowing `ref` to be used
for `in` parameters, and did not discuss changing this today.
2. At the declaration site, there is no way to indicate that being passed an rvalue from the call site is likely an error. This was our main discussion
today.
3. At the call site, lack of required `in` makes it unclear that a ref is being captured. This was not covered today, and we'll try to squeeze a
discussion in next meeting.

On the surface, points 2 and 3 appear to be a good fit for an analyzer, but we think there might an opportunity to address a lingering annoyance
from the original design of `in` parameters: the `in` keyword does not correspond to `ref readonly`, the keyword we use everywhere else throughout
the language for a similar concept. We see an opportunity to retcon `in` to be a modifier with extra behavior on top of `ref readonly`, much like
`out` is a modifier on top of `ref` with extra behavior on top. There is also the potential for an analyzer here to make the language _more_ complex,
not less, as now this spot in the table of declaration site modifiers/permitted call site forms would be taken by an analyzer, not by a native
language feature.

The history of `in` as a feature stretches back to the time some members of the LDT spent on the Midori project, where they had a custom version of
C# that supported a number of features, including a version of `ref readonly`. Initially, they used `ref readonly` as both the declaration site and
the call site modifier, but user feedback, particularly on the call site side, was immediate and vocal. To combat this, they brainstormed and
settled on `in` (first just at the call site, then eventually as a parameter modifier), as it's the natural counterpart to `out` and has been used
as a C# keyword since C# 1.0. This was then brought into C# in the C# 7 timeframe, as we added `ref struct`s based on Midori's experience in the
area. Midori, however, didn't have as many of these APIs where passing an rvalue was incorrect, as it had an expanded permissions system for
lifetime control. C# does not have this, so we think that `ref readonly` is a good change to make up for this.

Next, we will look at how `ref readonly` should affect the call site, and whether it should require that `ref`, `in`, or some other specifier to
be explicitly provided.

#### Conclusion

We upload the decision around `ref readonly` as a parameter modifier.
