# C# Language Design Meeting for January 29th, 2024

## Agenda

- [`params` collections](#params-collections)
  - [Better function member changes](#better-function-member-changes)
  - [`dynamic` support](#dynamic-support)
- [`dynamic` and `ref` local function bugfixing](#dynamic-and-ref-local-function-bugfixing)

## Quote of the Day

- "I got a new webcamera, I think I look kinda washed out... Insert C# joke"

## Discussion

### `params` collections

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

#### Better function member changes

https://github.com/dotnet/csharplang/blob/7a506890f909ea06d8b8396eb5e86a92c8482ade/proposals/params-collections.md#better-function-member

We started today by reviewing the proposed rules for how `params` collections will handle better function member. These rules generally try to apply the pre-existing
rules we have around `params` arrays to the new scenarios of `params` collections. However, we can't just think of these as "wrap the arguments with `[]`, and that's
the result you should get, as that already doesn't work for `params` arrays. As an example:

```cs
Test([1,2,3]); // error CS0121: The call is ambiguous between the following methods or properties: 'Program.Test(params int[])' and 'Program.Test(params long[])'
Test(1, 2, 3); // We pick 'static void Test(params int[] x)'

partial class Program
{
    static void Test(params int[] x) {}
    static void Test(params long[] x) {}
}
```

There are also some scenarios where `params` may be ambiguous where an explicit collection expression would not be, such as:

```cs
static void Test3()
{
    M3("3", ["4"]); // Span overload is used, better on the first argument conversion, none is better on the second
    M3("3", "4");   // Ambiguity, better-ness of argument conversions goes in opposite directions.
                    // Since parameter types are different ("object, string" vs. "string, object"), tie-breaking rules do not apply
}

static void M3(object x, params string[] y) {}
static void M3(string x, params Span<object> y) {}
```

However, we don't think these are common scenarios that need to be particularly concerned about, and they don't significantly affect the overall goal of making the
way that users conceive of the language simpler, even if some of the nitty-gritty edge cases will be more complex than they appear.

##### Conclusion

The rules are approved as proposed. We will watch early adopters (particularly the BCL) to make sure that there's no cases in the real world that we didn't think of
during this work.

#### `dynamic` support

https://github.com/dotnet/csharplang/blob/7a506890f909ea06d8b8396eb5e86a92c8482ade/proposals/params-collections.md#dynamic-vs-static-binding

Next, we looked at `dynamic` support. We don't expect the runtime binder to be updated to understand `params` collections, so we need to consider how to handle when we detect
that users are potentially going to encounter a runtime exception. We overall think that it's a good idea to try give warnings or errors when we know that candidates
will either be excluded or that there are no callable candidates.

##### Conclusion

The rules around `dynamic` binding are accepted as proposed.

### `dynamic` and `ref` local function bugfixing

https://github.com/dotnet/roslyn/issues/71399

Finally today, we looked at a bug in the C# compiler that was uncovered during the investigation into `params` collections. The decision on the previous section makes
fixing this more important, as it affects what "applicable" candidates appear during overload resolution. The main question we have is not whether to fix the bug, but
how broad to make the fix; do we report the error in _all_ language versions, or just in C# 13? This seems fairly low-risk: the compiler only has 1 test that is affected
by this, and the test covers a scenario that will fail at runtime anyway. We can revisit this later if it turns out to be a more broad breaking change.

#### Conclusion

We will fix this bug in all language versions.
