Skip to content

Latest commit

 

History

History
69 lines (47 loc) · 3.44 KB

LDM-2022-04-27.md

File metadata and controls

69 lines (47 loc) · 3.44 KB

C# Language Design Meeting for Apr 27th, 2022

Agenda

Quote of the Day

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

Discussion

Default parameter values in lambdas

#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:

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:

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

#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.