Added LDM Notes for May 10th, 2021.
This commit is contained in:
parent
03aedc0516
commit
3137df7cf4
95
meetings/2021/LDM-2021-05-10.md
Normal file
95
meetings/2021/LDM-2021-05-10.md
Normal file
|
@ -0,0 +1,95 @@
|
|||
# C# Language Design Meeting for May 10th, 2021
|
||||
|
||||
## Agenda
|
||||
|
||||
1. [Lambda improvements](#lambda-improvements)
|
||||
|
||||
## Quote of the Day
|
||||
|
||||
- "I'll allow it"
|
||||
|
||||
## Discussion
|
||||
|
||||
### Lambda improvements
|
||||
|
||||
#### Lambda natural types in unconstrained scenarios
|
||||
|
||||
There are a few related open questions around how we handle lambda expressions and method groups in unconstrained scenarios. These
|
||||
are scenarios such as:
|
||||
|
||||
```cs
|
||||
var a = (int x) => x; // What is the type of A?
|
||||
|
||||
void M1<T>(T t);
|
||||
M1((int x) => x); // What is the type of T?
|
||||
|
||||
void M2(object o);
|
||||
M2((int x) => x); // What is the type of the expression? ie, o.GetType() returns what?
|
||||
```
|
||||
|
||||
These scenarios are all related to how much we want to define a "default" function type in C#, and how much we think doing so could
|
||||
stifle later development around value delegates (if we even do such a feature). In C# today, we have 3 function types:
|
||||
|
||||
* Delegate types that inherit from `System.Delegate`.
|
||||
* Expression tree types that inherit from `System.Linq.Expressions.**Expression`.
|
||||
* Function pointer types.
|
||||
|
||||
All of these types support conversions from some subset of method groups or lambdas, and none is currently privileged above another.
|
||||
Overloads between these types are considered ambiguous, and users must explicitly include information that tells the compiler what
|
||||
type of function type to use, such as by giving a target type. If we allow `var`, conversions to `object`, and/or unconstrained generic
|
||||
type inference to work, we would be setting in stone what the "default" function type in C# is. This would be particularly noticeable
|
||||
if our future selves introduced a form of lightweight delegate types and wanted to make them the default in various forms of overload
|
||||
resolution. We are doing analogous work with interpolated strings currently, but interpolated strings are a much smaller section of
|
||||
the language than lambda expressions, and lambda irregularities are potentially much more noticeable.
|
||||
|
||||
We could protect our future selves here by making the spec more restrictive: Do not allow lambdas/method groups to be converted to
|
||||
unconstrained contexts. This would mean no `var`, no unconstrained type parameters, and no conversion to `object`. We would only infer
|
||||
when there was information that we could use to inform the compiler as to which type of function type to use: conversion to just
|
||||
`System.Delegate` would be fine, for example, because we know that the delegate type version was being chosen. While this would protect
|
||||
the ability to introduce a value delegate type later and make it the default, we see some potential usability concerns with making
|
||||
such a delegate type the default. At this point, we believe such a delegate type would be based on ref structs, and making `var`
|
||||
declare these types would be minefield for async and other existing scenarios. Using such types by default in generic inference would
|
||||
have similar issues around ref struct safety rules. And finally, if such a type were converted to `object`, it would by necessity need
|
||||
to be boxed somewhere, obviating the point of using a lightweight value delegate type in the first place. Given these concerns, we
|
||||
believe that we would just be protecting our ability to make the same decision later, and that another function type would not be a
|
||||
good "default".
|
||||
|
||||
##### Conclusion
|
||||
|
||||
We allow inferring a natural type for a lambda or method group in unconstrained scenarios, inferring Action/Func/synthesized delegate
|
||||
type, as appropriate.
|
||||
|
||||
#### Type inference
|
||||
|
||||
We went over the rules as specified in the proposal. The only missing bit is that, at final usage, a function type needs to look at
|
||||
constraints to determine whether it should be inferred to be a Delegate or an Expression.
|
||||
|
||||
##### Conclusion
|
||||
|
||||
Accepted, with the additional step around constraints.
|
||||
|
||||
#### Direct invocation
|
||||
|
||||
Finally today, we looked at supporting direct invocation of lambda expressions. This is somewhat related to the
|
||||
[first topic](#lambda-natural-types-in-unconstrained-scenarios), but could be implemented even if we chose to do the restrictive version
|
||||
of that issue because this feature would not require us to actually choose a final function type for the lambda expression. We could
|
||||
just emit it as a method and call it directly, without creating a delegate instance behind the scenes at all. However, we don't have an
|
||||
important driving scenario behind this feature: technically it could be used as a form of statement expression, but it doesn't feel like
|
||||
a good solution to that problem. The main thing we want to make sure works is regularity with other inferred contexts:
|
||||
|
||||
```cs
|
||||
// If this works
|
||||
var zeroF = (int x) => x;
|
||||
var zero = zeroF(0);
|
||||
|
||||
// This should also work
|
||||
var zero = ((int x) => x)(0);
|
||||
|
||||
// But this wouldn't work with var, so is it fine to have not work here?
|
||||
var zero = (x => x)(0);
|
||||
```
|
||||
|
||||
##### Conclusion
|
||||
|
||||
We generally support the idea, even the final example. It may take more work however, and thus may not make C# 10. We'll create a
|
||||
more formal specification for approval.
|
|
@ -20,21 +20,23 @@
|
|||
## May 17, 2021
|
||||
|
||||
- Raw string literals (cyrusn): https://github.com/dotnet/csharplang/issues/4304
|
||||
- *Triage championed features and milestones*
|
||||
|
||||
## May 12, 2021
|
||||
|
||||
- Experimental attribute (Immo): https://github.com/dotnet/designs/blob/main/accepted/2021/preview-features/preview-features.md
|
||||
- Simple C# programs (Phillip): https://github.com/dotnet/designs/pull/213
|
||||
|
||||
## May 10, 2021
|
||||
|
||||
- Lambda / method group natural type (Chuck, Mads): https://github.com/dotnet/csharplang/pull/4728
|
||||
- *Triage championed features and milestones*
|
||||
|
||||
# C# Language Design Notes for 2021
|
||||
|
||||
Overview of meetings and agendas for 2021
|
||||
|
||||
## May 10, 2021
|
||||
|
||||
[C# Language Design Notes for May 10th, 2021](https://github.com/dotnet/csharplang/blob/master/meetings/2021/LDM-2021-05-10.md)
|
||||
|
||||
- Lambda improvements
|
||||
|
||||
## May 3, 2021
|
||||
|
||||
[C# Language Design Notes for May 3rd, 2021](https://github.com/dotnet/csharplang/blob/master/meetings/2021/LDM-2021-05-03.md)
|
||||
|
|
Loading…
Reference in a new issue