# C# Language Design Meeting for Apr 27th, 2022

## Agenda

- [Default parameter values in lambdas](#default-parameter-values-in-lambdas)
- [Null-conditional assignment](#null-conditional-assignment)

## Quote of the Day

- "I don't like broccoli, don't make me eat it"

## Discussion

### Default parameter values in lambdas

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

In another iteration on lambdas, we looked at a gap that lambdas cannot expression, but local functions can: default parameter values.
There are two schools of thought on this feature, which differ by whether we generate custom delegate types for these lambdas or whether
we just use `Action`/`Func` and require runtime introspection of the delegate instance to determine default parameters. The former feature
will allow compile-time usage of the default parameter values, while the latter would mean that the main use case would be introspection
features, such as reflection or source-generators.

This latter proposal is interesting, but we think it's likely the wrong approach. A feature that can only be observed via reflection or
source generation doesn't seem like it integrates well with the rest of C#, and if we ever want to change it in the future the breaking
change would likely be quite painful. There is, however, one interesting case that was enabled with C# 10:

```cs
var m = M; // Infers Action<int>
m(); // Error: no value provided for arg0

void M(int i = 1) {}
```

This case doesn't generate a custom delegate type, and compiles today. We think that this isn't great behavior, and that we should change
it in C# 11, before `var` for method groups has time to hugely penetrate large codebases.

We also thought about how strict we should be on matching default parameter values. For example, should this code be an error:

```cs
var x = (int i = 1) => {};
x = (int i = 2) => {}; // Reassigned with a different underlying default.
x(); // What would this pass for i?
```

We again have precedent with method groups, but with a slight difference: method groups converted to delegates are one _possible_ way to
call such methods. It is conceivable that there is intentionally a different default value for directly calling a method vs calling it
via some delegate type, or the method could come from assembly that the user doesn't control. Lambdas don't have this: they can only be
converted to a delegate type, and are defined by the user, not by some other library. Thus, we think it's worth a warning for lambda
default parameter value mismatches; it's technically well-defined and the compiler understands what it means, but it's very likely the
user is doing something wrong. We could consider a warning wave for method groups mismatches as well, but that will have to depend on
whether we thing the signal-noise ratio would be high enough.

#### Conclusion

Feature is accepted. We will generate custom delegate types for these lambdas, and accept the breaking change to do the same for method groups.
We will warn when lambda parameter default values differ from a delegate type they are converted to, if the lambda is not being converted
to its natural type.

### Null-conditional assignment

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

We're looking at old, well-upvoted request: allowing a null-conditional on the left side of an assignment. We generally think it's a good
feature, even if `a?.b ??= c` has a very different meaning from `a?.b ?? c`.

#### Conclusion

Proposal accepted, moved into the working set.
