Added LDM Notes for May 10th, 2021.

This commit is contained in:
Fredric Silberberg 2021-05-10 15:45:59 -07:00
parent 03aedc0516
commit 3137df7cf4
No known key found for this signature in database
GPG key ID: BB6144C8A0CEC8EE
2 changed files with 102 additions and 5 deletions

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

View file

@ -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)