www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - What is the state of property?

reply Ki Rill <rill.ki yahoo.com> writes:
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
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
next sibling parent Ki Rill <rill.ki yahoo.com> writes:
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.

 -Steve
Thank 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
prev sibling next sibling parent bauss <jacobbauss gmail.com> writes:
On Thursday, 25 August 2022 at 03:49:07 UTC, Steven Schveighoffer 
wrote:
 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
Personally I use it for documentation as it makes it clear what the intentions are of said functions.
Aug 25 2022
prev sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
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
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/28/22 9:43 AM, Salih Dincer wrote:
 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 ```
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. -Steve
Aug 28 2022
next sibling parent Salih Dincer <salihdb hotmail.com> writes:
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
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/28/22 6:36 PM, Steven Schveighoffer wrote:
 On 8/28/22 9:43 AM, Salih Dincer wrote:
 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 ```
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.
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.
Aug 29 2022
next sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
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
prev sibling parent reply Guillaume Piolat <first.last spam.org> writes:
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
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 30/08/2022 2:45 AM, Guillaume Piolat wrote:
 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.
It only does two things: 1. I can't remember the (single) semantic behavior 2. Create threads like this one Time to go.
Aug 29 2022
parent Salih Dincer <salihdb hotmail.com> writes:
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
prev sibling next sibling parent reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
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
next sibling parent reply bauss <jacobbauss gmail.com> writes:
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:
 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).
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?
Aug 25 2022
parent reply Salih Dincer <salihdb hotmail.com> writes:
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
parent reply frame <frame86 live.com> writes:
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:
 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:
That has nothing to do with property, it works with ("") too.
Aug 26 2022
parent Salih Dincer <salihdb hotmail.com> writes:
 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
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
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
parent Andrey Zherikov <andrey.zherikov gmail.com> writes:
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 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.
I didn't know that! Shame on me 🤦
Aug 25 2022
prev sibling next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
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
prev sibling parent zako <user example.net> writes:
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
prev sibling parent cc <cc nevernet.com> writes:
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