@property fields
Quirin Schroll
qs.il.paperinik at gmail.com
Thu Jan 16 00:47:47 UTC 2025
On Tuesday, 3 December 2024 at 23:50:20 UTC, Richard (Rikki)
Andrew Cattermole wrote:
> The ``@property`` attribute has been left in the lurch for
> quite some time, where only one behaviour related to its return
> value being of any value.
>
> There are two parts of this proposal, however I am only
> confident in the first part, fields.
> The other is for methods which would give you full control over
> it.
>
> Syntax is quite simple:
>
> ``@property int field;``
>
> It is valid in interfaces, structs, and classes.
>
> ```d
> interface IField {
> @property int field;
> }
>
> class Thing : IField {
> @property int field;
> }
>
> struct Thing2 {
> @property int field;
> }
> ```
>
> It results in three things.
>
> 1. A field that is either ``protected`` (classes) or
> ``private`` (structs).
>
> ```d
> class Thing : IField {
> protected int field;
> }
>
> struct Thing2 {
> private int field;
> }
> ```
>
> If we have struct inheritance, then it would be
> ``protected`` instead.
>
> 2. It will generate a method for classes and structs in the
> form:
>
> ```d
> class Thing : IField {
> protected int field;
>
> ref typeof(this.field) __property_field() /* inferred
> attributes */ {
> return this.field;
> }
> }
>
> struct Thing2 {
> private int field;
>
> ref typeof(this.field) __property_field() /* inferred
> attributes */ {
> return this.field;
> }
> }
> ```
>
> 3. A method stub is generated for the property field in an
> interface:
>
> ```d
> interface IField {
> ref typeof(this.field) __property_field();
> }
> ```
>
> You may place attributes around the field to apply to the
> method.
>
> ```d
> interface IField {
> @safe:
> @property int field;
> }
> ```
>
> This allows an interface to require that a field exists,
> without defining one. Since it is the stub that gets inherited
> (which can only be implemented using an ``@property`` field.
>
> Semantically:
>
> 1. You will not have direct access to the field outside of the
> type. All accesses and mutation will go through the method.
> 2. It may be passed to a function parameter that is ``ref`` or
> ``out``. This is perfectly safe so needs no protection due to
> it implicitly being ``scope``.
> 3. An invariant will be called following mutation or when it is
> passed to a ``ref`` or ``out`` function
> parameter.
> 3.1. For interfaces if a ``@property`` field is used, an
> invariant will be required to be in the vtable implicitly.
> 4. In ``@safe`` code:
> 4.1. It may not be stored in a ref variable ``ref var =
> thing.field;``
> 4.2. It may not have a pointer taken to it ``&thing.field``
>
> As long as the invariant is called after mutation, this covers
> the use case of setter methods for properties. It cannot be
> used to transform, but will cause errors. If you need
> transformation wrapping the field with a struct could introduce
> such behaviors so need not be provided at this level (although
> it should be supported with ``@property`` methods).
This reminds me of [this C#
proposal](https://github.com/dotnet/csharplang/blob/main/proposals/field-keyword.md). You’re proposing something quite similar, just the other way around. Your idea is to define the backing field and annotate it to request the getter and setter be defined.
TL;DR: The C# proposal adds a contextual `field` keyword that,
when used in the getter or setter of a property, refers to an
implicitly generated backing field.
More information about the dip.ideas
mailing list