Create LDM-2020-04-13.md

This commit is contained in:
Mads Torgersen 2020-04-13 13:57:21 -07:00 committed by GitHub
parent 88202acd40
commit c5428f507f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -0,0 +1,77 @@
# C# Language Design for April 13, 2020
## Agenda
1. Roadmap for records
2. Init-only properties
# Roadmap for records
We want to break down the records feature in a way that gets incremental steps out to partner teams and users sooner, and lets us iterate based on feedback. So what order should we do things in?
Two demanding aspects of records that are certainly important but can probably be done later are:
1. Primary constructors (allowing positional parameters directly on record types)
2. Inheritance to and from record types
So a proposal is to split those off in the first iteration of implementation.
## Decision
We do need to get those right to ultimately ship the feature! However, we want to start by building a version of records that:
* Is nominal only (no primary constructor)
* Inherits from object and can't be inherited from
* Special-cases `with` expressions to `With` methods rather than rely on a "Factory" feature
* Fully implements value equality
For this to be useful we need the init-only property feature at the same time as well, so that there is *some* way to create and initialize immutable records.
In subsequent iterations we will
* Add support for inheritance to records
* Add primary constructors to records
* Generalize the `With` implementation to use factories
* Decide on and embrace defaults (`public` by default?) and abbreviations
On parallel tracks we will work on:
* Factory methods
* Validators?
* Mandatory properties?
* Primary constructors as a general feature?
# Init-only members
Init-only properties are the most urgent separate feature to nail down, as the experience of even the first iteration of records depends on them. There are a couple of design decisions still left open; we address them here.
## Should we have init-only fields?
Readonly fields today can only be assigned during construction, and only through a `this` access within the body of the class that declares the field. As we extend the concept of "initialization time" to cover execution of init-only setters (by object initializers in client code) as well as validators (if we add those to the language), it makes sense that `readonly` fields should be assignable from within those kinds of members as well.
We would *not* allow readonly fields to be directly assigned in an object initializer, however, as that would undermine the expectation that the class author has full control over how and when they are assigned.
Allowing init-only properties to assign readonly fields would address most of the init-only scenario: An object initializer can be used to set immutable state on the newly created object. A dedicated init-only form of fields is not needed for that. It probably *does* have valid scenarios (in programming styles where immutable fields are themselves public), but those seem less central. We could wait see if that rises to the importance of a seperate, subsequent feature.
### Decision
Let's allow init-only property setters (and validators, if and when we add them) to assign to `readonly` fields of the same object.
Let's not add init-only fields now. We can consider a new kind of field that can be initialized directly in object initializers later, as a separate feature, if we become convinced that it's worthwhile.
## Syntax
Should the setters of init-only properties be called `init` or `init set`? In other words, is `init` a modifier on the `set` accessor, or does it replace it completely?
Shorter is generally nicer. However, we do foresee a (near?) future where `init` as a modifier could be applied to other members and accessors, to mean that they can only run during initialization (and in return would get privileges such as assigning to readonly members).
### Decision
`init` it is. `init` as a modifier is an interesting feature, but we can discuss it separately. If we do, we can consider allowing `init set` as a long form of an init-only setter for regularity when code has `init` modifiers in multiple places. But for now, let's just allow `init` instead of `set`.
## Init-only indexers
Indexers also have `set` accessors. Should they also be allowed to declare an `init` accessor instead?
### Decision
It makes perfect sense, is somewhat useful, would be more regular in the language, and has straightforward semantics. Let's do it.