Added LDM Notes for October 20th, 2021.
This commit is contained in:
parent
e8ddd37721
commit
9f54c9673f
93
meetings/2021/LDM-2021-10-20.md
Normal file
93
meetings/2021/LDM-2021-10-20.md
Normal file
|
@ -0,0 +1,93 @@
|
|||
# C# Language Design Meeting for October 20th, 2021
|
||||
|
||||
## Agenda
|
||||
|
||||
1. [Open questions in list patterns](#open-questions-in-list-patterns)
|
||||
1. [Types that define both Length and Count](#types-that-define-both-length-and-count)
|
||||
2. [Slices that return null](#slices-that-return-null)
|
||||
2. [Primary constructors](#primary-constructors)
|
||||
|
||||
## Quote of the Day
|
||||
|
||||
- "No fingerprints today, I always struggle with it after a bank robbery, when I file them down"
|
||||
|
||||
## Discussion
|
||||
|
||||
### Open questions in list patterns
|
||||
|
||||
https://github.com/dotnet/csharplang/issues/5137
|
||||
|
||||
We had 3 open questions from tests on list patterns. Questions 1 and 2 both relate to types with both `Length` and `Count` properties, so our decision
|
||||
applies to both.
|
||||
|
||||
#### Types that define both Length and Count
|
||||
|
||||
Our previous definition of a type that can be matched by a list pattern is that the type must be both indexable and countable. Because countable could be
|
||||
one of two properties, `Length` or `Count`, we need to decide what do when a type has both. Our options are:
|
||||
|
||||
1. Treat them as equivalent and assume they return the same value. This will affect subsumption.
|
||||
2. Treat the non-recognized one (`Count` in the case where both `Length` and `Count` are defined) as not being special at all.
|
||||
|
||||
Conceptually, we think it would be odd to assume that `Count` is equal to `Length`, even though we'll never use it for any form of slicing or length checking.
|
||||
While it might be reasonable to assume they return the same value, we don't think it's an important scenario. We'll have nearly a year of preview on this
|
||||
feature, so we have plenty of time to react to feedback if dogfooding shows that it's an important scenario.
|
||||
|
||||
##### Conclusion
|
||||
|
||||
We will not treat `Length` and `Count` as being connected when both are defined.
|
||||
|
||||
#### Slices that return null
|
||||
|
||||
We believe that well-defined slice methods should never return `null` for an in-bounds range, and we'll never generate a call to such a slice method with
|
||||
an out-of-bounds range. However, we also don't think there's a customer for this scenario: a search of GitHub showed no `Slice` methods that return an
|
||||
annotated value, and treating a slice method differently than its annotation would require both implementation effort and customer education. Given that
|
||||
there are no known cases this affects, we don't think it's worth it. Similarly to the first question, if such scenarios are identified during preview, we
|
||||
can correct appropriately.
|
||||
|
||||
##### Conclusion
|
||||
|
||||
If a `Slice` method is annotated, we will treat it as potentially returning `null` for the purposes of subsumption and exhaustiveness.
|
||||
|
||||
### Primary constructors
|
||||
|
||||
https://github.com/dotnet/csharplang/issues/2691
|
||||
|
||||
Now that records have been out for a year and we've expanded them to struct and reference types, we think it's time to start looking at primary constructors
|
||||
again. We updated the proposal with the new syntax forms from our records work, removing or modifying components where they make sense. Unlike for records,
|
||||
primary constructors aren't about defining the members that make up a grouping of data: instead, they're purely for defining the inputs to a class. So things
|
||||
like deconstruction, equality, and public properties aren't automatically generated from the parameters. Instead, they become fields, that are then eliminted if
|
||||
the field is never used outside of a field initializer.
|
||||
|
||||
We think there are a couple of open discussion topics:
|
||||
|
||||
1. Should the fields be readonly or not?
|
||||
2. How important are primary constructor bodies for a generalized feature?
|
||||
|
||||
For question 1, we think that, for better or for worse, C# is a mutable-by-default language. We were able to change the defaults for `record` types because
|
||||
mutability in a value-based reference type is actively harmful, but we have to consider a number of naming and mutability issues we were able to skirt around
|
||||
in record types. Field naming conventions, for example, are heavily split in C#, with some users using a leading `_`, and some preferring to just use pascalCase
|
||||
with no leading modifiers. We think `readonly` is similar: if users would like to modify the defaults of C#, they can define their own field and do so. If this
|
||||
proves to be the wrong default we can make a change before it ships for real, or potentially invest in https://github.com/dotnet/csharplang/issues/188 to allow
|
||||
putting modifiers on parameters.
|
||||
|
||||
For question 2, we think that it will be important, but that once https://github.com/dotnet/csharplang/issues/2145 is in the language, a good portion of
|
||||
initialization code will be expressable in just a single initialization expression. It will miss some more complex scenarios, but we think just primary constructors
|
||||
are a good first step.
|
||||
|
||||
In general, we also want to make sure we're defining the difference between primary constructors and required properties well. With the potential for multiple new
|
||||
initialization features to ship in a single language version, we want to make sure they complement each other well. We think required properties work well for
|
||||
public contracts: DTOs, POCOs, and other similar, nominal data structures that will expose these properties externally. Primary constructors, on the other hand,
|
||||
are for other types, that do not define public surface area based on their parameters. Instead, they simply define input parameters, and can assign them to private
|
||||
fields or otherwise manipulate them as they choose.
|
||||
|
||||
Some concrete feedback on the proposal:
|
||||
|
||||
* The exception for calling `this` for copy constructors feels premature, as they don't mean anything to any type except record types. If we generalize `with` in
|
||||
the future, then the exception will make sense, and we can add it then.
|
||||
* We should disallow methods with the same name as primary constructor parameters. This is confusing and while it could potentially be understandable code if the
|
||||
parameter was never captured, could then have spooky action at a distance if the parameter was accidentally captured when a user forgot to write the `()` of the
|
||||
method name.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
These words are accepted.
|
|
@ -15,15 +15,19 @@ All schedule items must have a public issue or checked in proposal that can be l
|
|||
|
||||
## Oct 25, 2021
|
||||
|
||||
## Oct 20, 2021
|
||||
|
||||
- Open questions with `Length`/`Count` assumptions in context of list-patterns (Julien): https://github.com/dotnet/csharplang/issues/5137
|
||||
- Primary constructors (Mads): https://github.com/dotnet/csharplang/blob/main/proposals/non-record-primary-constructors.md
|
||||
|
||||
# C# Language Design Notes for 2021
|
||||
|
||||
Overview of meetings and agendas for 2021
|
||||
|
||||
## 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)
|
||||
|
||||
1. Open questions in list patterns
|
||||
1. Types that define both Length and Count
|
||||
2. Slices that return null
|
||||
2. Primary constructors
|
||||
|
||||
## Oct 13, 2021
|
||||
|
||||
[C# Language Design Notes for October 13th, 2021](https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-10-13.md)
|
||||
|
|
Loading…
Reference in a new issue