# C# Language Design Meeting for Apr 24, 2024

## Agenda

- [Adjust dynamic binding rules for a situation of a single applicable candidate](#adjust-dynamic-binding-rules-for-a-situation-of-a-single-applicable-candidate)

## Quotes of the day

"Once people are in dynamic-land they've already chosen"

## Adjust dynamic binding rules for a situation of a single applicable candidate

(https://github.com/dotnet/csharplang/pull/8027)

The params collection work includes some changes to how binding occurs if either the primary expression or an argument is dynamic. When there is only one candidate, it could be used.

This change caused [unexpected breaking changes in certain cases](https://github.com/dotnet/roslyn/issues/72750):

> ```csharp
> using System.Text.Json;
> 
> public class C
> {
>     public static C M(IFoo foo, dynamic value)m
>     {
>         var result = foo.Bar("name", value);
>         return JsonSerializer.Deserialize<C>(result);
>     }
> }
> 
> public interface IFoo
> {
>     object Bar(string name, object value);
> }
> ```
> 
> After the recent changes around dynamic, the type of result is now object whereas previously it was dynamic.


### Discussion

It is desirable to use use static binding to make more things possible with dynamics. This can be done when there is only one applicable candidate.

#### Dynamic or static result

We do not plan to change things that work today, such as local functions. We are only considering whether new cases should have a static result or be "dynamified"

There were concerns about returning static results from operations with dynamic being surprising. Constructors do this, but that is because you are stating the return type explicitly in the call to `new`.

There are some some opinions voiced that we should avoid to avoid unnecessary dynamic proliferation (although what is unnecessary may be opinion).

It was pointed out that part of the core of the design of dynamic that it is contagious. There is worry about needing a decoder ring to know when the results are static or dynamic. 

General feeling that consistency along with back compatibility considered is desirable.

Prior art: VB has had runtime dynamic since V1. `Object` in VB is dynamic. It delays resolution to runtime. When there is only a single candidate that is applicable it would do static binding and not change the result to `Object'. It does not proliferate dynamic.

VB might also be considered a lesson learned because of ambiguity between dynamic and the base type. The dual role of object may drive VB being static when possible, dynamic when necessary.

Whether we should use static or dynamic result types when we use static binding with dynamic arguments in new scenarios was not resolved today. We will return to this question.

#### Static binding can uncover more errors during compilation

There are cases where static binding allows us to know that certain cases, like assigning to void, would fail at runtime. We can now give a compile time error for these cases and it would be desirable to do so.

#### Scenarios from proposal

These scenarios from the proposal framed the discussion and conclusions:

> 1. the candidate is not a local function;
> 2. the candidate returns a value (doesn't have type `void`, doesn't return a `ref`);
> 3. there is an implicit conversion from result type to `dynamic`;
> 4. the receiver and argument list would be supported for dynamically bound invocation.

- Bullet 1 is an existing scenario that is enshrined.
- Bullet 2 and 3 are moving errors from runtime to compile time.
- Bullet 4 is under discussion because success scenarios have non-dynamic results that we may choose to "dynamify".


## Conclusions

We can use static binding as an implementation strategy when dynamic binding isn't supported. (From 30,000 feet - taking something that would have always failed, and making it work.)

We can change runtime error scenarios to compile-time error scenarios.

We should tie these changes to language version.
