Added LDM Notes for September 15th and 20th.

This commit is contained in:
Fredric Silberberg 2021-09-20 18:21:14 -07:00
parent c1ccfd0d6a
commit 4109c3d3de
No known key found for this signature in database
GPG key ID: BB6144C8A0CEC8EE
3 changed files with 257 additions and 12 deletions

View file

@ -0,0 +1,73 @@
# C# Language Design Meeting for September 15th, 2021
## Agenda
* [Feedback from the C# standardization committee](#feedback-from-the-c-standardization-committee)
* [Permit pattern variables under disjunctive patterns](#permit-pattern-variables-under-disjunctive-patterns)
## Quote of the Day
- "We've so far decided not to decide"
## Discussion
### Feedback from the C# standardization committee
https://github.com/dotnet/csharpstandard/issues/366
For the first half of today's LDM, we had a guest from the C# standardization committee on to talk about the ongoing process by TC-49
to produce an update to the ECMA C# specification, the latest version of which covers C# 5. In the csharplang repository, we currently
have an initial conversion of an internal Microsoft C# specification of C# 3, which was updated to cover some aspects of C# 6. The ECMA
team has converted the C# 5 specification to markdown, and is currently working to integrate the changes from our C# 6 spec into that
version.
These dual versions of the specification can confuse users. The language reference on docs.microsoft.com comes from the csharplang
version of the spec, but the TC-49 version of this specification has had a number of bug fixes and is a better markdown conversion overall.
Because of this the csharplang version of the spec gets occasional pull requests to update various things, from English spelling and
grammar issues to actual spec bugs, but many times those issues have already been fixed in the TC-49 version of the specification. To
address this, we plan to remove the csharplang version of the specification when the last PRs for C# 6 are merged into the csharpstandard
repo, which should hopefully be soon.
Additionally, the standardization committee has draft PRs out for most C# 7 features, and is working on C# 8 specifications as well.
Currently, when they run into questions they've been emailing a few specific compiler team members, who hopefully can either answer their
questions or forward to the right team member. To facilitate better interactions, we've created an internal alias with the compiler team,
the language design team, and the TC-49 members currently working on the draft specifications. The specification changes for C# 8 are big,
particularly with nullable reference types, and will require close collaboration between these groups to make sure the spec actually reflects
the feature that was implemented by the compiler team.
Finally, we did some thinking about how to collaborate moving forward on new language features. We'd like to think about maintaining proposals
as branches on the TC-49 specification, to make sure that we are considering the real specification when we think about new language features
and ensuring that we can see other proposed changes to the specification as a whole when making new features, as opposed to having to remember
what not-yet-specified proposal from a previous language version modified a particular section of the specification while designing a new
change to that section.
### Permit pattern variables under disjunctive patterns
https://github.com/dotnet/csharplang/issues/4018
We took a first pass over this proposal in the second half of the LDM. At first brush, there are a couple of major points of contention:
1. Should we allow redeclaration, or should we have some from of `into` pattern that would allow the reuse of an existing variable in
a pattern?
2. Is variable declaration across multiple expressions ok, or should it only be permissible within a single pattern?
Point 1 arises from potential confusion around the double declaration: will users find the multiple declarations intuitive, or will they
wonder about "which" of the pattern variables future usages refer to? We've also had requests for an `into` pattern in the past, that would
allow a pattern to assign into an existing variable. We're concerned about a generalized version of this pattern because it could have
unpredictable effects, particularly when combined with `when` clauses, but a more specialized version that can only use variables declared
in the same pattern could be a usable version of this proposal. We also want to think about how this would interact with any potential
pattern matching over types themselves in the future, such as extracting the `T` from an `IEnumerable<T>`: if such a thing could be done,
it should be doable under an `or` as well, and we will want to have similar syntax forms for redeclaration as here. We also need consider
how an `into` pattern or other form of assignment syntax would interact if we ever want to permit non-constants to be used as a pattern
themselves.
For point 2, we're concerned about the potential large impact throughout the language. This would be very similar to permitting a
generalized `into` pattern, where `when` clauses can cause otherwise-matching patterns to not be executed and reassign existing variables.
Several members of the LDM feel that we should tackle just within a single expression first, and consider multiple expressions at a later
time with more examples of the types of code it would enable.
#### Conclusions
No conclusions today. We want to see the specification PR updated with more motivating samples, including samples from real code, before
we make any conclusions on these issues.

View file

@ -0,0 +1,168 @@
# C# Language Design Meeting for September 20th, 2021
## Agenda
1. [Lambda breaking changes](#lambda-breaking-changes)
2. [Newlines in non-verbatim interpolated strings](#newlines-in-non-verbatim-interpolated-strings)
3. [Object initializer event hookup](#object-initializer-event-hookup)
4. [Type alias improvements](#type-alias-improvements)
## Quote of the Day
- "You're kicking in an open door"
## Discussion
### Lambda breaking changes
https://github.com/dotnet/roslyn/pull/56341
In the ever continuing saga of new breaking changes introduced by giving method groups and lambda expressions natural types, we looked
at a few new breaking changes today to decide what, if any, workarounds we should adopt to try and fix them.
#### Breaking changes around overload resolution
https://github.com/dotnet/roslyn/issues/55691
https://github.com/dotnet/roslyn/issues/56167
https://github.com/dotnet/roslyn/issues/56319
https://github.com/dotnet/csharplang/discussions/5157
We have a number of reports from users who have been broken by changes in overload resolution, mostly because a set of overloads that
used to succeed in overload resolution are now ambiguous. A smaller group met to discuss a number of different potential solutions to
the issue. These options where:
1. Leave the breaking changes as-is.
2. Change “method type inference” and “best common type” to not infer from the natural type of a lambda expression or method group.
3. Change “better function member” to treat delegate types with identical signatures as equivalent, allowing tie-breaking rules to apply.
4. Change “better function member” to prefer overloads where method type inference did not infer type arguments from the natural types
of lambdas or method groups.
5. Change “better function member” to prefer parameter types that are delegate types other than those used for natural type. (Prefer D
over Action.)
6. Change “better function member” to prefer argument conversions other than “function type” conversions.
7. Change “better function member” to prefer parameter types D or Expression<D> over Delegate or Expression, where D is a delegate type.
Discussion further narrowed our focus to two combinations of the above options: 3+7 or 4+6. 3+7 results in a more aggressive break, while
4+6 is more compatible with previous versions of C#. Given the extent of some of the breaks we're seeing, we think the more compatible
approach is the better way to go, so we'll proceed with the PR linked at the start of this section.
##### Conclusion
Options 4+6 accepted.
#### Method groups converting to `Expression`
Another break testing has revealed looks like this:
```cs
var c = new C();
c.M(F); // C#9: E.M(); C#10: error CS0428: Cannot convert method group 'F' to 'Expression'.
static int F() => 0;
class C
{
public void M(Expression e) { Console.WriteLine("C.M"); }
}
static class E
{
public static void M(this object o, Func<int> a) { Console.WriteLine("E.M"); }
}
```
We think we would have a solution for this: split our "function type conversion" into two separate conversion types: a function type
conversion from lambda, and a function type conversion from method group. Only the former would have a conversion to Expression. This
would make it so that `M(Expression)` is not applicable if the user passed a method group, leaving only `M(object, Func<int>)`. This
could be a bit complex, but it should resolve the issue.
Unlike the previous examples, however, we don't have any reports of this issue. Given the number of reports of the previous breakages
we've received, and the lack of reports for this issue, we tentatively think that it's not worth fixing currently. If, after we ship
C# 10 for real, we received reports of this break, we know how to fix it and can change course at that time without making a breaking
change.
##### Conclusion
No changes will be made.
#### Lambdas in OHI
A final break we looked at today is:
```cs
using System;
B.F1(() => 1); // C#9: A.F1(); C#10: B.F1()
var b = new B();
b.F2(() => 2); // C#9: A.F2(); C#10: B.F2()
class A
{
public static void F1(Func<int> f) { }
public void F2(Func<int> f) { }
}
class B : A
{
public static void F1(Delegate d) { }
public void F2(Delegate d) { }
}
```
This is standard OHI behavior in C#, but because the derived overloads were previously not applicable, they were not included in the
`B.F1` or `b.F2` method groups, and only the methods from `A` would be applicable. Now that methods from the more derived type are
applicable, methods from the base type are filtered out by method group resolution.
We think this is both fine and actually desirable behavior. We don't have contravariant parameters in C#, but this is effectively
acting like such, which is a good thing. This change is also not customer-reported, but was instead discovered in testing. Given the
desirable behavior and lack of reports, we think no change is necessary.
##### Conclusion
No changes.
### Newlines in non-verbatim interpolated strings
https://github.com/dotnet/csharplang/issues/4935
We have a lot of compiler complexity around ensuring interpolated strings do not have a newline in them, and we don't see a real
reason to forbid newlines. We think the origin might have come from the number of different design flip-flops we made on interpolated
strings during their initial design.
#### Conclusion
Language change approved.
### Object initializer event hookup
https://github.com/dotnet/csharplang/issues/5176
LDM is not only interested in this change, we're also interested in generalized improvements that can be made in object initializers
and with expressions. Compound assignment is interesting, particularly in `with` expressions, and we would like to see what improvements
we could make not just for events, but for all types of properties and fields.
#### Conclusion
Approved. We want to explore even more enhancements in this space.
### Type alias improvements
https://github.com/dotnet/csharplang/issues/4284
Finally today, we looked at one of the open questions in this proposal: how should we handle nullable types in using aliases when the
alias is used in a `#nullable disable` location.
There are largely 2 ways to view using aliases:
1. Syntactic substitutions: the compiler is literally copy/pasting the thing in the alias into the target location. In this view, the
compiler should treat the syntax as occuring at the use point, and warn based on that.
2. Semantic substitutions: the using alias is effectively defining a new type. It's not a truly different type, but only the meaning
is substituted, not the actual syntax. If we ever want to consider a way to export using aliases, this will be a useful meaning to assume.
We also have some (possibly unintended) prior art here: `using MyList = System.Collections.Generic.List<string?>;` takes the second
approach today, acting like a semantic substitution.
The one thing we still want to consider in this space is top-level nullability. We're not sure about allowing a type alias to have
top-level nullability when it's an alias to a reference type. There is (very intentionally) no extra C# syntax for "not null reference
type" beyond the lack of a `?`, and the next ask if we were to allow aliases to be top-level nullable would be for such a syntax.
#### Conclusion
Overall, we like the semantic meaning. We still need to consider whether aliases should be allowed to have top-level nullability.

View file

@ -24,22 +24,26 @@ All schedule items must have a public issue or checked in proposal that can be l
- Open questions with list patterns (Julien): https://github.com/dotnet/csharplang/issues/5201
- Triage (Mads): https://github.com/dotnet/csharplang/issues?q=is%3Aopen+is%3Aissue+label%3A%22Proposal+champion%22+no%3Amilestone
## Sep 20, 2021
- C# 10: Open questions with lambdas (Chuck): see spec changes in https://github.com/dotnet/roslyn/pull/56341 description
- Type aliases (Cyrus): https://github.com/dotnet/csharplang/issues/4284
- `+=` for events in object initializers (Cyrus): https://github.com/dotnet/csharplang/issues/5176
- Remove restriction that interpolations within a non-verbatim interpolated string cannot contain new-lines (cyrusn): https://github.com/dotnet/csharplang/issues/4935
## Sep 15, 2021
- Feature specs and the C# Standard (Mads, Bill, Rex): https://github.com/dotnet/csharpstandard
- Permit variable declarations under disjunctive patterns (Julien): draft proposal https://github.com/dotnet/csharplang/pull/4592
# C# Language Design Notes for 2021
Overview of meetings and agendas for 2021
## Sep 20, 2021
[C# Language Design Notes for September 20th, 2021](https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-09-20.md)
1. Lambda breaking changes
2. Newlines in non-verbatim interpolated strings
3. Object initializer event hookup
4. Type alias improvements
## Sep 15, 2021
[C# Language Design Notes for September 15th, 2021](https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-09-15.md)
* Feedback from the C# standardization committee
* Permit pattern variables under disjunctive patterns
## Sep 13, 2021
[C# Language Design Notes for September 13th, 2021](https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-09-13.md)