Added LDM Notes for October 25th, 2021
This commit is contained in:
parent
ec01d26c47
commit
2802e29f4c
104
meetings/2021/LDM-2021-10-25.md
Normal file
104
meetings/2021/LDM-2021-10-25.md
Normal file
|
@ -0,0 +1,104 @@
|
|||
# C# Language Design Meeting for October 25th, 2021
|
||||
|
||||
## Agenda
|
||||
|
||||
1. [Required members](#required-members)
|
||||
2. [Delegate type argument improvements](#delegate-type-argument-improvements)
|
||||
|
||||
## Quote of the Day
|
||||
|
||||
- "It's officially late, not casually late"
|
||||
|
||||
## Discussion
|
||||
|
||||
### Required members
|
||||
|
||||
https://github.com/dotnet/csharplang/issues/3630
|
||||
|
||||
It's been nearly a year since we last looked at required members, so we started today by recaping the proposal as it currently
|
||||
[exists](https://github.com/dotnet/csharplang/blob/ec01d26c47d8d3e3e10b1dd0ade96dae6f99934a/proposals/required-members.md). We also
|
||||
took a look at the feedback we received when this was last shown to our design review team (mainly internal partners and former
|
||||
language design members who aren't involved the day-to-day design of the language anymore). The feedback we received at that point
|
||||
was that the proposal, as it currently stands, is too complex. We have a lot of syntax for enabling a set of contract modifications:
|
||||
|
||||
1. Users can say `init(Prop)` to signal that the constructor requires all things the type does, except the members in the `init` clause.
|
||||
2. Users can say `init required` to signal that the constructor does not require any of the members the type does, and the compiler
|
||||
will ensure that the user correctly initializes all members in that constructor.
|
||||
3. Users can say `init required!` to signal the same 2, except that the compiler will not enforce that the user correctly initializes
|
||||
all members in that constructor.
|
||||
|
||||
This syntax was quite specialized, as we intended it to be extensible enough that future work around factories would be able to take
|
||||
advantage of the same syntax. However, upon coming back to the syntax, we have several people that changed their opinions on the form;
|
||||
some of the people that didn't originally feel like the syntax "clicked" now like it, and others that originally liked it now think that
|
||||
it doesn't work well. We took a look at the concrete cases that will want to use the above modifications:
|
||||
|
||||
* Copy constructors will want to opt out of the entire contract, as their job is to initialize all the fields to the original instance's
|
||||
values.
|
||||
* Types might have a grow-up story, where they may originally ship with just some number of required properties, but later may want to add
|
||||
a convenience constructor that sets a few common properties. We think that this case, while not unreasonable, is not the common case for
|
||||
this feature.
|
||||
|
||||
The first use case wants at least contract modification 3, and possibly 2 as well. It does not need 1. The second case needs contract
|
||||
modification 1 to be expressible in C#. Given this, we think that there's a gradual approach we can take to introducing contract
|
||||
modifications to the language. A potential first approach is just introducing modification 3, without any constructor body validation.
|
||||
A later version of the language can, as part of a warning wave, turn on body validation, and then later allow individual member exceptions
|
||||
as in modification 1. We are a bit split on this decision, however. We think a prototype to play around with that implements this initial
|
||||
decision should help inform the initial feature set we want to ship for this feature. One thing we definitely don't want to do is ship
|
||||
without constructor body validation and without feeling like we can make that the default state later via a warning wave, as that would
|
||||
leave us in a bad position where validation is available, but off by default.
|
||||
|
||||
We also looked at different syntax forms, namely attributes. We'd considered attributes previously in the design, but steered away from
|
||||
them to see what we could do with language-integrated syntax. We think we've gone as far down that road as we can, but our final design
|
||||
still doesn't feel quite right. Given that, we think that having an attribute to express the contract modifications will serve us well.
|
||||
It can be named more verbosely, should still be able to apply to factory methods, and required no new syntax for users to learn.
|
||||
|
||||
Finally, we also considered a couple of other questions:
|
||||
|
||||
* Should we have a new accessor, `req`, that is used for a required property instead of `init`?
|
||||
* We think that this use case is too small, cuts out required setters, and cuts out the ability to mark fields as required.
|
||||
* Should we use a warning or error on construction? Traditionally, "suppressions" correspond to warnings, and the contract modifications
|
||||
can be viewed as suppressing the need to initialize things.
|
||||
* They're not really suppressions though. It's changing the semantics of the code, so we think it's fine (and safer) for us to use
|
||||
errors on construction, not warnings.
|
||||
* We haven't considered how required members will interact with `default(StructType)`. Some thought needs to be put into that.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
We will start working on an implementation of the simplified version of this proposal that uses attributes for contract modifications,
|
||||
not specific syntax, and only has contract modification 3. Feedback will then inform whether we need 2 or 1 before we ship.
|
||||
|
||||
### Delegate type argument improvements
|
||||
|
||||
https://github.com/dotnet/csharplang/issues/5321
|
||||
|
||||
A couple of weeks ago, Microsoft held our annual internal hackathon, and one of the ideas that we worked on for the it this year was
|
||||
relaxing type argument restrictions, specifically for delegate types. This would allow delegate types such as `Action<void>` or
|
||||
`Action<in int, ref readonly Span<char>>`, where these types are restricted from use in delegate types today. In general, the LDM has
|
||||
a lot of interest in this space, but there is some concern that this proposal doesn't go far enough in relaxing restrictions, and might
|
||||
run into issues if we try to generalize it more fully. A very common pattern in generic code in C# is to further abstract over parameter
|
||||
types: for example, a method might take a `Func<T, bool>` and a `T`, and pass the `T` parameter to the `Func<T, bool>` invocation. This
|
||||
proposal falls apart for such methods, which is a very early cliff to fall over. If we can instead generalize this work, such that these
|
||||
restricted types are allowed in more places, then we'd be in a much better position. Even if we don't ship the whole thing at once, we'd
|
||||
really like to make sure we're not painting ourselves into a hole with a proposal like this.
|
||||
|
||||
As a part of this, we also want to explore a revamp to the .NET delegate story. Today, `Action` and `Func` are the de-facto delegate types
|
||||
in C#: they're used throughout the BCL and lambdas/method groups use them where possible for their natural type. However, there are limits
|
||||
to this, as custom delegate types still have some advantages:
|
||||
|
||||
* Ref kinds/restricted type arguments. This is solved by the current proposal as it stands.
|
||||
* Parameter names. We don't think this would be very difficult to solve, as we have prior art with tuple names.
|
||||
* Attributes. This is much more difficult to accomplish, to avoid needing to synthesize custom delegate types we'd need to have some way of
|
||||
putting attributes on a type argument. The runtime does not support this today, and it won't be as simple to add as the type restriction
|
||||
removals were.
|
||||
|
||||
We've been moving towards structural typing of delegates ever since `Action` and `Func` were introduced, and we think it might be a better
|
||||
approach to the problem to start from fully structural delegate types, and work backwards to see how we could make that work. It's very
|
||||
likely that we'd end up doing some of the same work generalizing on `Action` and `Func`, but there's some additional interesting wrinkles
|
||||
around `Action` and `Func<void>`. We might be able to unify these two, but we then want to be able to do the same for other types. How
|
||||
would we make it work for `Task` and `Task<void>`, for example? Is there some attribute we could add to the runtime that would allow it
|
||||
to treat these types as identical, forwarding from one to the other? And how would that flow through the C# type system?
|
||||
|
||||
#### Conclusions
|
||||
|
||||
We don't have any conclusions today. We think that much more exploration of this space is needed before moving forward with any specific
|
||||
proposal. We want to look into generalizing the generic restriction removals, and into generalized structural typing for delegates.
|
|
@ -28,15 +28,17 @@ All schedule items must have a public issue or checked in proposal that can be l
|
|||
- Utf8 strings (Jared): _writeup in the works_
|
||||
- Primary constructors and readonly fields feedback (Fred, Cyrus): https://github.com/dotnet/csharplang/discussions/5314
|
||||
|
||||
## Oct 25, 2021
|
||||
|
||||
- Required properties recap (Fred): https://github.com/dotnet/csharplang/blob/main/proposals/required-members.md
|
||||
- Improved delegate type arguments (Rikki): https://github.com/dotnet/csharplang/issues/5321
|
||||
|
||||
# C# Language Design Notes for 2021
|
||||
|
||||
Overview of meetings and agendas for 2021
|
||||
|
||||
## Oct 25, 2021
|
||||
|
||||
[C# Language Design Notes for October 25th, 2021](https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-10-25.md)
|
||||
|
||||
1. Required members
|
||||
2. Delegate type argument improvements
|
||||
|
||||
## Oct 20, 2021
|
||||
|
||||
[C# Language Design Notes for October 20th, 2021](https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-10-20.md)
|
||||
|
|
Loading…
Reference in a new issue