From ff18bac738791bfb3e11155e3e5b6398c2c49d71 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Wed, 8 Apr 2020 14:54:50 -0700 Subject: [PATCH] Add LDM notes for April 6, 2020 --- meetings/2020/LDM-2020-04-06.md | 86 +++++++++++++++++++++++++++++++++ meetings/2020/README.md | 10 ++-- 2 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 meetings/2020/LDM-2020-04-06.md diff --git a/meetings/2020/LDM-2020-04-06.md b/meetings/2020/LDM-2020-04-06.md new file mode 100644 index 0000000000..e58f8c6374 --- /dev/null +++ b/meetings/2020/LDM-2020-04-06.md @@ -0,0 +1,86 @@ + +# C# Language Design Notes for April 6th, 2020 + +## Agenda + +Init-only members + +## Discussion + +We have a proposal to dive into: https://github.com/jaredpar/csharplang/blob/init/proposals/init.md + +* The proposal notes that you can set `init` fields of the base type during construction, similar + to `readonly`. This is not how `readonly` works today, only the declaring type can set readonly + fields + +* The proposal allows `init` on class and struct declarations as a shorthand for `init` on types. + This is different from how `readonly` struct works today, where there is no syntactic shorthand, + `readonly` simply adds the additional requirement that all instance fields are marked `readonly`. + +* For the runtime: does this feature prohibit runtime restrictions on setting `readonly` instance + fields in the future? Put simply: yes. To avoid breaking C#, the runtime would be required to + either respect the proposed `InitOnlyAttribute`, or restrict optimizations to not alter the code + for these features. + +* Use in interfaces: the proposal prohibits it, but the following example seems useful: + + ```C# + interface I + { + int Prop { get; init set; } + } + + public void MyMethod() where T : I, new() + { + var t = new T() { + Prop = 1 + }; + } + ``` + +* Signature compatibility: should `init` properties be compatible with mutable ones? That is, should + removing `init` in favor of a bare `set` be binary-compatible? This impacts our decisions for how + we think about safety in older compilers: + + * If we use a modreq to prevent other compilers from unsafely using a `setter`, that affects the + signature of the method, and would make the above a breaking change + + * If we want accept that older compilers are not a problem (C#, VB, and F# will all be updated), + perhaps we don't need to specially guard this at all + + * We could use attributes to mark *and* guard, by using the `Obsolete` attribute. `ref struct`s + use this guard by having an Obsolete attribute with a reserved message, that is ignored by + compatible compilers. + +### Accessors + +Should we allow three accessors: `get, set, init`? A big problem here is that you can end up +calling instance members in a constructor that invoke the setter, not the initter, for a +property. This means that there are few, if any, invariants that hold for init vs. set, and +weakens the feature significantly. + +### Syntax + +`init` vs. `initonly` for syntax. On the one hand, `init` is inconsistent with `readonly` (vs. `initonly`), but on the other hand we're pretty sad that `readonly` is such a long keyword. It also has few analogies +with properties, where `readonly` isn't allowed at all, and the shorter `init` keyword seems more similar to +`get` and `set` + + * Usage of `init` as a modifier: there are a number of different meanings here, and similarities + between `readonly` and `init` is separating the more places we use it. For instance, if `init` is + allowed as a member modifier, it seems similar to `readonly` on members, but they actually do + different things. Moreover, `readonly` on types means that all instance fields and methods are + `readonly`, while `init` on types would only mean `init` on fields, not on methods. + + * What are the uses for `init` methods, aside from helper methods? Could they be used in collection initializers? + +### Required Initialization + +The proposal in this doc is that required initialization is also an important feature for setters. We're +going to leave that discussion for a future meeting. As proposed, nullable warnings are not modified for +`init` members. + +**Conclusions** + +No `init` on types. No agreement on syntax. We probably have to talk about more of the use cases. +We've decided that having three different accessors is not helpful. Settled that we will place a +`modreq` on all `init` setters. diff --git a/meetings/2020/README.md b/meetings/2020/README.md index db4e06f930..76e11189c3 100644 --- a/meetings/2020/README.md +++ b/meetings/2020/README.md @@ -37,10 +37,6 @@ - Record Monday (Andy, Mads) -## April 6, 2020 - -- Record Monday: Init-only properties deep dive (Jared) - ## March 18, 2020 - https://github.com/jaredpar/csharplang/blob/record/proposals/recordsv3.md clone-style records (Jared) @@ -70,6 +66,12 @@ Overview of meetings and agendas for 2020 3. Inferred type of an `or` pattern 4. Module initializers +## April 6, 2020 + +[C# Language Design Notes for April 6, 2020](https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-04-06.md) + +1. Record Monday: Init-only members + ## April 1, 2020 [C# Language Design Notes for April 1, 2020](https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-04-01.md)