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

## Agenda

- [Collection Literals](#collection-literals)
    - [`Create` methods](#create-methods)
    - [Extension methods](#extension-methods)
- [Interceptors](#interceptors)

## Quote of the Day

- "I prefer the correct pronunciation, in-foof"

## Discussion

### Collection Literals

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

#### `Create` methods

https://github.com/dotnet/csharplang/blob/52b90748d1ebab0268468eb5dc8e954bc98c2834/proposals/collection-literals.md#create-methods

We started by looking at the initialization pattern the working group and the BCL team have been working on. This pattern has changed a bit from the last
time it was presented: now, instead of an `out Span` that the compiler would write into, the compiler passes in a `ReadOnlySpan`, which the collection will
then copy out of. Methods would be discovered by looking for a specific attribute on the target type, which then tells the compiler what the build type is
and what method name to look for. This has some amount of `methodof` to it, but in a much more restrictive sense; overload resolution is not involved at all.
The compiler looks for a method in the type explicitly referenced, with the name explicitly specified, with exactly the parameter list `ReadOnlySpan<TElement>`.
Questions of things like default parameters or element type conversions don't play into it. Given these restrictions, we're ok with this pattern. It might be
expanded in the future, but we think that our bases on breaking changes are well covered.

##### Conclusion

Pattern approved, modulo BCL naming feedback.

#### Extension methods

https://github.com/dotnet/csharplang/blob/e566e33620e3f6671a7042a3e23cd1120ff04c76/proposals/collection-literals.md#extension-methods

Next, we turned our attention to extension methods on collection literals. There were a few components to our discussion. First, assumed that extensions were
allowed, and thought about element type conversions; put simply, would this work?

```cs
var byteArray = [4].ToArray<byte>(); // Converts from int->byte
```

[Previously](LDM-2023-06-19.md#collection-literals), we made an analogy between collection literals and tuples. We think that analogy applies here, as an
equivalent extension method would not work on a tuple, nor would it work for just an integer literal.

Next, we looked at the broader scenario. These extension methods really exist for two reasons:

* Allowing the compiler to infer the element type of a collection, while still providing explicit information about the collection type.
* Allowing the type information to be put on the right side of the collection.

Both features seem orthogonal to collection literals (https://github.com/dotnet/csharplang/issues/1349 is the former, and
https://github.com/dotnet/csharplang/issues/4076 is very similar to the latter). Moreover, other typeless expressions seem like they could benefit from similar
treatment. There's therefore a 3rd possible orthogonal feature:

* Allow extension methods on expressions with no natural type.

In any case, we think that this is a separate enough feature that we don't want to roll it in with collection literals, but instead want to take the time to
explore the 3 options here to their conclusions for C# 13.

##### Conclusion

Extension support specifically for collection literals rejected, we will explore the broader features for C# 13.

### Interceptors

https://github.com/dotnet/roslyn/blob/d71ec683082104e9122a4937abc768710c5f7782/docs/features/interceptors.md

Finally today, we took another look at the current state of interceptors. When we last discussed them and decided that they should be a compiler feature, we
changed how we thought of the general idea; we now consider it effectively an instrumentation step, similar to inserting sequence points for debugging purposes.
Since then, there's been a decent amount of development progress, one of the most controversial among the LDM is the removal of `InterceptableAttribute`. There's
two main lines of argument here:

* Opposing the change, there's concern about spooky action at a distance. In some ways, removing the attribute turns this feature into an unrestricted `comefrom`,
  otherwise known as the satirical inverse to `goto`. There were also arguments that this is very similar to `InternalsVisibleTo` vs `IgnoreAccessChecksTo`; the
  compiler supports the former, but not the latter.
* Supporting the change, if a user came to the BCL and asked them to put `Interceptable` on some public API, when could the BCL realistically say no? These are
  are public APIs, not like the internal implementation details that access checks exist to protect. The user _can_ work around them by just calling a different
  method (possibly even just adding an extension with the same signature, just with `Interceptable` appended to the name), so the original method author being
  involved in the decision is odd.

Another thing that's important to note is that this feature is very explicitly still experimental, and will still be experimental in .NET 8, so we're not locked
into any decision permanently if we determine that it's incorrect after some end-user testing.

We did not reach any conclusions here today, but the interceptors group has a good amount of feedback to go discuss and come back to in a couple of weeks.
