digitalmars.D - What is the state of property?
- Ki Rill (4/4) Aug 24 2022 It's not recommended to use it, yet people do continue using it
- Steven Schveighoffer (19/22) Aug 24 2022 It's not even 1/10 baked.
- Ki Rill (5/8) Aug 24 2022 Thank you, Steven, for the detailed reply. I will continue
- bauss (4/29) Aug 25 2022 Personally I use it for documentation as it makes it clear what
- Salih Dincer (18/29) Aug 28 2022 The function has parameters, the difference you're pointing isn't
- Steven Schveighoffer (9/35) Aug 28 2022 You are asking for the type of the expression which calls the function.
- Salih Dincer (30/34) Aug 28 2022 We still need @property where specified
- Andrei Alexandrescu (14/50) Aug 29 2022 I think this should be immortalized and made very clear in the docs.
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (15/18) Aug 29 2022 Nitpick - this actually does work:
- Guillaume Piolat (8/11) Aug 29 2022 So this is the state of @property:
- rikki cattermole (5/19) Aug 29 2022 It only does two things:
- Salih Dincer (6/10) Aug 29 2022 😀
- Andrey Zherikov (27/31) Aug 25 2022 Why is it not recommended?
- bauss (5/36) Aug 25 2022 I'm really not sure what you mean.
- Salih Dincer (29/32) Aug 25 2022 One benefit of @property is that it allows the compiler to infer
- frame (2/9) Aug 26 2022 That has nothing to do with @property, it works with @("") too.
- Salih Dincer (62/66) Aug 26 2022 ```d
- Mike Parker (4/8) Aug 25 2022 That works by default without `@property`, and has since way, way
- Andrey Zherikov (2/10) Aug 25 2022 I didn't know that! Shame on me 🤦
- rikki cattermole (16/19) Aug 25 2022 It already does. That is the problem!
- zako (21/25) Aug 29 2022 dmd.50 docs (2002):
- cc (10/10) Sep 02 2022 I use @property, with the full knowledge that it does mostly
It's not recommended to use it, yet people do continue using it anyway... I see it in people's code. So, was it finalized, but docs weren't updated? Or is it still half-backed? And what is the issue?
Aug 24 2022
On 8/24/22 11:26 PM, Ki Rill wrote:It's not recommended to use it, yet people do continue using it anyway... I see it in people's code. So, was it finalized, but docs weren't updated? Or is it still half-backed? And what is the issue?It's not even 1/10 baked. It does just about nothing. The only discernable difference is `typeof`: ```d struct S { int prop1() { return 1; } property int prop2() { return 2; } } pragma(msg, typeof(S.prop1)); // int() pragma(msg, typeof(S.prop2)); // int ``` What is the issue? The attribute was added with the intention that properties would require a property attribute, and functions would not. But there was pushback, so it never got formalized. For a while we had a `-property` switch which would enforce some rules, but it was also removed. As of today, I'd ignore property. If someone is using it, just pretend it's a normal function. -Steve
Aug 24 2022
On Thursday, 25 August 2022 at 03:49:07 UTC, Steven Schveighoffer wrote:As of today, I'd ignore property. If someone is using it, just pretend it's a normal function. -SteveThank you, Steven, for the detailed reply. I will continue ignoring it. Anyways, we have `inout` functions, and the functionality is the same.
Aug 24 2022
On Thursday, 25 August 2022 at 03:49:07 UTC, Steven Schveighoffer wrote:On 8/24/22 11:26 PM, Ki Rill wrote:Personally I use it for documentation as it makes it clear what the intentions are of said functions.It's not recommended to use it, yet people do continue using it anyway... I see it in people's code. So, was it finalized, but docs weren't updated? Or is it still half-backed? And what is the issue?It's not even 1/10 baked. It does just about nothing. The only discernable difference is `typeof`: ```d struct S { int prop1() { return 1; } property int prop2() { return 2; } } pragma(msg, typeof(S.prop1)); // int() pragma(msg, typeof(S.prop2)); // int ``` What is the issue? The attribute was added with the intention that properties would require a property attribute, and functions would not. But there was pushback, so it never got formalized. For a while we had a `-property` switch which would enforce some rules, but it was also removed. As of today, I'd ignore property. If someone is using it, just pretend it's a normal function. -Steve
Aug 25 2022
On Thursday, 25 August 2022 at 03:49:07 UTC, Steven Schveighoffer wrote:It does just about nothing. The only discernable difference is `typeof`: ```d struct S { int prop1() { return 1; } property int prop2() { return 2; } } pragma(msg, typeof(S.prop1)); // int() pragma(msg, typeof(S.prop2)); // int ```The function has parameters, the difference you're pointing isn't even visible :) ```d struct S { int prop1(int a) { return a; } property int prop2(int b) { return b; } } pragma(msg, typeof(S.prop1(1))); // int pragma(msg, typeof(S.prop2(2))); // int ``` **PS.** I could not work my last code in [the playground](https://run.dlang.io). The reason is `writeln`'s choices. I guess new version doesn't get along well with ` property`... SDB 79
Aug 28 2022
On 8/28/22 9:43 AM, Salih Dincer wrote:On Thursday, 25 August 2022 at 03:49:07 UTC, Steven Schveighoffer wrote:You are asking for the type of the expression which calls the function. (i.e. `typeof(s.prop2(1))` instead of `typeof(s.prop2)`. However, `typeof(s.prop2)` is going to fail, because the compiler is requiring property functions to be used when using `typeof` (and only when using `typeof`). I'm trying to tell you this is the *only thing ` property` does*. In all other cases, it's indistinguishable from a normal function/method. -SteveIt does just about nothing. The only discernable difference is `typeof`: ```d struct S { int prop1() { return 1; } property int prop2() { return 2; } } pragma(msg, typeof(S.prop1)); // int() pragma(msg, typeof(S.prop2)); // int ```The function has parameters, the difference you're pointing isn't even visible :) ```d struct S { int prop1(int a) { return a; } property int prop2(int b) { return b; } } pragma(msg, typeof(S.prop1(1))); // int pragma(msg, typeof(S.prop2(2))); // int ```
Aug 28 2022
On Sunday, 28 August 2022 at 15:36:41 UTC, Steven Schveighoffer wrote:In all other cases, it's indistinguishable from a normal function/method.We still need property where specified [here](https://dlang.org/spec/type.html#typeof) **⁵**. When you compile the example in the code window below, you get the following error:onlineapp.d(17): Error: variable `onlineapp.main.test1` cannot be declared to be a function```d struct S { // property float Float() { return .0; } property double Double() { return .0; } } void main() { S s; typeof(s.Float) test1 = s.Float; typeof(s.Double) test2 = s.Double; import std.stdio; typeid(test1).writeln(": ", test1); typeid(test2).writeln(": ", test2); } ``` This is what I wanted to talk about above. So it changes dignity of function (correct word?). SDB 79
Aug 28 2022
On 8/28/22 6:36 PM, Steven Schveighoffer wrote:On 8/28/22 9:43 AM, Salih Dincer wrote:I think this should be immortalized and made very clear in the docs. It's an FAQ. (FWIW it's also a sign that the feature is not very helpful.) One possibility to make it more useful would be to have property disallow function signatures that cannot possibly be used as properties (e.g. multiple non-defaulted parameters). Also properties that return UDTs by value are suspect because they lead to confusing code. Consider: struct Widget { int a; } property Widget w() { return Widget.init; } // should be disallowed void main() { w.a = 42; // does nothing, looks like it's assigning a value } Assigning values to fields of rvalues is a distinct long-standing problem.On Thursday, 25 August 2022 at 03:49:07 UTC, Steven Schveighoffer wrote:You are asking for the type of the expression which calls the function. (i.e. `typeof(s.prop2(1))` instead of `typeof(s.prop2)`. However, `typeof(s.prop2)` is going to fail, because the compiler is requiring property functions to be used when using `typeof` (and only when using `typeof`). I'm trying to tell you this is the *only thing ` property` does*. In all other cases, it's indistinguishable from a normal function/method.It does just about nothing. The only discernable difference is `typeof`: ```d struct S { int prop1() { return 1; } property int prop2() { return 2; } } pragma(msg, typeof(S.prop1)); // int() pragma(msg, typeof(S.prop2)); // int ```The function has parameters, the difference you're pointing isn't even visible :) ```d struct S { int prop1(int a) { return a; } property int prop2(int b) { return b; } } pragma(msg, typeof(S.prop1(1))); // int pragma(msg, typeof(S.prop2(2))); // int ```
Aug 29 2022
On Monday, 29 August 2022 at 08:40:51 UTC, Andrei Alexandrescu wrote:One possibility to make it more useful would be to have property disallow function signatures that cannot possibly be used as properties (e.g. multiple non-defaulted parameters).Nitpick - this actually does work: ``` void prop(int i, float f, string s) {} void main() { import std.typecons : tuple; import std.meta : AliasSeq; prop = tuple(1, 2.0, "foo").expand; prop = AliasSeq!(1, 2.0, "foo"); } ``` Should it, though? Probably not. -- Simen
Aug 29 2022
On Monday, 29 August 2022 at 08:40:51 UTC, Andrei Alexandrescu wrote:I think this should be immortalized and made very clear in the docs. It's an FAQ. (FWIW it's also a sign that the feature is not very helpful.)So this is the state of property: - takes valuable time to discuss, over and over, for years - serve no purpose other than "documentation", so it could be a phobos/druntime UDA - it creeps up in code and PR, and each time needs an explanation This is a net negative feature.
Aug 29 2022
On 30/08/2022 2:45 AM, Guillaume Piolat wrote:On Monday, 29 August 2022 at 08:40:51 UTC, Andrei Alexandrescu wrote:It only does two things: 1. I can't remember the (single) semantic behavior 2. Create threads like this one Time to go.I think this should be immortalized and made very clear in the docs. It's an FAQ. (FWIW it's also a sign that the feature is not very helpful.)So this is the state of property: - takes valuable time to discuss, over and over, for years - serve no purpose other than "documentation", so it could be a phobos/druntime UDA - it creeps up in code and PR, and each time needs an explanation This is a net negative feature.
Aug 29 2022
On Monday, 29 August 2022 at 15:04:20 UTC, rikki cattermole wrote:It only does two things: 1. I can't remember the (single) semantic behavior 2. Create threads like this one Time to go.😀 I look on the positive side and I learn a lot thanks to you. Like property I love all of them even if some don't work, I love D, thank you everyone. SDB 79
Aug 29 2022
On Thursday, 25 August 2022 at 03:26:32 UTC, Ki Rill wrote:It's not recommended to use it, yet people do continue using it anyway... I see it in people's code. So, was it finalized, but docs weren't updated? Or is it still half-backed? And what is the issue?Why is it not recommended? It's useful when you need to evolve API and migrate users from one data member to another, for example: ```d struct S { property string old_member() const { return new_member; } string new_member; } ``` Or when you want to do some audit: ```d struct S { property string member() const { writeln("'member' is used by ", environment["USER"]); return _member; } string _member; } ``` I have no objections to deprecate ` property` attribute but I believe D must support the use case when `obj.mem` expression calls `obj.mem()` function (this is usually called property functions).
Aug 25 2022
On Thursday, 25 August 2022 at 13:18:38 UTC, Andrey Zherikov wrote:On Thursday, 25 August 2022 at 03:26:32 UTC, Ki Rill wrote:I'm really not sure what you mean. Currently property doesn't really do anything in this regard, so I imagine that the code would work the same without property, no?It's not recommended to use it, yet people do continue using it anyway... I see it in people's code. So, was it finalized, but docs weren't updated? Or is it still half-backed? And what is the issue?Why is it not recommended? It's useful when you need to evolve API and migrate users from one data member to another, for example: ```d struct S { property string old_member() const { return new_member; } string new_member; } ``` Or when you want to do some audit: ```d struct S { property string member() const { writeln("'member' is used by ", environment["USER"]); return _member; } string _member; } ``` I have no objections to deprecate ` property` attribute but I believe D must support the use case when `obj.mem` expression calls `obj.mem()` function (this is usually called property functions).
Aug 25 2022
On Thursday, 25 August 2022 at 13:23:25 UTC, bauss wrote:Currently property doesn't really do anything in this regard, so I imagine that the code would work the same without property, no?One benefit of property is that it allows the compiler to infer automatically. So it behaves like auto but superior! For example: ```d import std.stdio; struct ReverseS(int size) { private char[size] bytes; private int index = size - 1; property empty() { return index < 0; } property front() { return bytes[index]; } property popFront() { --index; } } void main() { char[9] text = "ytreporp ".dup; foreach(c; ReverseS!9(text)) { c.write; } writeln; // property } ``` SDB 79
Aug 25 2022
On Thursday, 25 August 2022 at 14:49:51 UTC, Salih Dincer wrote:On Thursday, 25 August 2022 at 13:23:25 UTC, bauss wrote:That has nothing to do with property, it works with ("") too.Currently property doesn't really do anything in this regard, so I imagine that the code would work the same without property, no?One benefit of property is that it allows the compiler to infer automatically. So it behaves like auto but superior! For example:
Aug 26 2022
On Thursday, 25 August 2022 at 14:49:51 UTC, Salih Dincer wrote: One benefit of property is that it allows the compiler to infer automatically. So it behaves like auto but superior! For example:```d import std.stdio, std.format : conv = format; //version = 1; void main() { char[6] text = "abcDEF".dup; auto VERSION = VerA!6(text); // sub-versions // range for sure (all version!) foreach(c; VERSION) c.write; "(empty == true)".writeln; // VerA.0, VerB.0: front() => D (one character) // VerA.1, VerB.1: toString() => abcDEF (all) //VERSION.writeln;/* VerA!6(text).writeln; VerB!6(text).writeln; //*/ } struct VerA(int len) { char[len] bytes; int index = len / 2; property/* system//*/ { alias front this; bool empty() { return index == len; } char front() { return bytes[index]; } void popFront() { ++index; } } version(1) { string toString() { return conv("%s", bytes); } } } struct VerB(int len) { char[len] bytes; int index = len / 2; alias front this; property/* system//*/ { bool empty() { return index == len; } char front() { return bytes[index]; } void popFront() { ++index; } } version(1) { string toString() { return conv("%s", bytes); } } } ``` I discovered another feature of property while accessing it with writeln(). You need the alias and InputRange elements to see this... Have I got it right? When accessing the structure with writeln(), if there is toString(), it is executed first, otherwise InputRange elements come into play. Just like we did with foreach(). If you scope the InputRange elements into the property scope, the alias becomes priority. It's the opposite when you scope it to system. SDB 79
Aug 26 2022
On Thursday, 25 August 2022 at 13:18:38 UTC, Andrey Zherikov wrote:I have no objections to deprecate ` property` attribute but I believe D must support the use case when `obj.mem` expression calls `obj.mem()` function (this is usually called property functions).That works by default without ` property`, and has since way, way back in the early D1 days.
Aug 25 2022
On Thursday, 25 August 2022 at 13:25:58 UTC, Mike Parker wrote:On Thursday, 25 August 2022 at 13:18:38 UTC, Andrey Zherikov wrote:I didn't know that! Shame on me 🤦I have no objections to deprecate ` property` attribute but I believe D must support the use case when `obj.mem` expression calls `obj.mem()` function (this is usually called property functions).That works by default without ` property`, and has since way, way back in the early D1 days.
Aug 25 2022
On 26/08/2022 1:18 AM, Andrey Zherikov wrote:I have no objections to deprecate ` property` attribute but I believe D must support the use case when `obj.mem` expression calls `obj.mem()` function (this is usually called property functions).It already does. That is the problem! ```d import std; void main() { S s; s.new_member = "foo"; s.old_member.writeln; } struct S { string old_member() { return new_member; } string new_member; } ```
Aug 25 2022
On 25.08.22 15:18, Andrey Zherikov wrote:I have no objections to deprecate ` property` attribute but I believe D must support the use case when `obj.mem` expression calls `obj.mem()` function (this is usually called property functions).dmd.50 docs (2002): -- All this is quite a bit of typing, and it tends to make code unreadable by filling it with getProperty() and setProperty() calls. In D, get'ers and set'ers take advantage of the idea that an lvalue is a set'er, and an rvalue is a get'er: class Abc { int myprop; void property(int newproperty) { myprop = newproperty; } // set'er int property() { return myprop; } // get'er } which is used as: Abc a; a.property = 3; // equivalent to a.property(3) int x = a.property; // equivalent to int x = a.property() Thus, in D you can treat a property like it was a simple field name. A property can start out actually being a simple field name, but if later if becomes necessary to make getting and setting it function calls, no code needs to be modified other than the class definition. --
Aug 29 2022
I use property, with the full knowledge that it does mostly nothing, for self-documentation purposes, in places where I'd use similar semantics in other languages. Seeing that I tagged something with property lets me infer certain things about the nature of the inner values being held by the object, the interface to the outside world, and how the result is likely to be used once it's retrieved. Adding property to a function looks warm and comfortable, like hanging a little holiday wreath on its door. I enjoy using it and I'm not going to stop. I use property more than safe.
Sep 02 2022