www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is the current stage of property ?

reply Vinod K Chandran <kcvinu82 gmail.com> writes:
Hi all,
I read in an old thread that authors of D wants to eliminate 
 property. I just roughly read the big thread bu couldn't find a 
conclusion. After all that thread is a 48 page longer jumbo 
thread. So out of curiosity, i am asking this. What is the 
current state of  property ? Is it deprecated ?
Jun 10 2020
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 10 June 2020 at 20:24:19 UTC, Vinod K Chandran 
wrote:
 Hi all,
 I read in an old thread that authors of D wants to eliminate 
  property. I just roughly read the big thread bu couldn't find 
 a conclusion. After all that thread is a 48 page longer jumbo 
 thread. So out of curiosity, i am asking this. What is the 
 current state of  property ? Is it deprecated ?
The current state of property is that it doesn't really do anything. D allows you to call functions without parentheses, and to use assignment syntax to call a single-argument function, so you can write getters and setters that work like properties even if you don't use the property annotation: struct Example { private int x_; int x() { return x; } // getter void x(int n) { x = n; } // setter } void main() { Example e; e.x = 123; // calls setter int y = e.x; // calls getter }
Jun 10 2020
next sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Wednesday, 10 June 2020 at 21:40:44 UTC, Paul Backus wrote:
 On Wednesday, 10 June 2020 at 20:24:19 UTC, Vinod K Chandran 
 wrote:
 Hi all,
 I read in an old thread that authors of D wants to eliminate 
  property. I just roughly read the big thread bu couldn't find 
 a conclusion. After all that thread is a 48 page longer jumbo 
 thread. So out of curiosity, i am asking this. What is the 
 current state of  property ? Is it deprecated ?
The current state of property is that it doesn't really do anything. D allows you to call functions without parentheses, and to use assignment syntax to call a single-argument function, so you can write getters and setters that work like properties even if you don't use the property annotation: struct Example { private int x_; int x() { return x; } // getter void x(int n) { x = n; } // setter } void main() { Example e; e.x = 123; // calls setter int y = e.x; // calls getter }
It can't do binary operations and unary operations.
Jun 10 2020
parent reply Vinod K Chandran <kcvinu82 gmail.com> writes:
On Wednesday, 10 June 2020 at 22:15:25 UTC, 12345swordy wrote:

 It can't do binary operations and unary operations.
12345swordy, You mean we can't do such ops inside the property ?
Jun 10 2020
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Wednesday, 10 June 2020 at 22:30:37 UTC, Vinod K Chandran 
wrote:
 On Wednesday, 10 June 2020 at 22:15:25 UTC, 12345swordy wrote:

 It can't do binary operations and unary operations.
12345swordy, You mean we can't do such ops inside the property ?
No, it means you can't do this: e.x += 123;
Jun 10 2020
prev sibling parent Vinod K Chandran <kcvinu82 gmail.com> writes:
On Wednesday, 10 June 2020 at 21:40:44 UTC, Paul Backus wrote:

 The current state of  property is that it doesn't really do 
 anything. D allows you to call functions without parentheses, 
 and to use assignment syntax to call a single-argument 
 function, so you can write getters and setters that work like 
 properties even if you don't use the  property annotation:


 struct Example
 {
     private int x_;
     int x() { return x; } // getter
     void x(int n) { x = n; } // setter
 }

 void main()
 {
     Example e;
     e.x = 123; // calls setter
     int y = e.x; // calls getter
 }
Paul Backus, Thanks for the explanation & code sample.
Jun 10 2020
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jun 10, 2020 at 08:24:19PM +0000, Vinod K Chandran via
Digitalmars-d-learn wrote:
 Hi all,
 I read in an old thread that authors of D wants to eliminate
  property. I just roughly read the big thread bu couldn't find a
 conclusion. After all that thread is a 48 page longer jumbo thread. So
 out of curiosity, i am asking this. What is the current state of
  property ? Is it deprecated ?
It's stuck in limbo, like many things that people just cannot agree on. There are a few places where it's needed (like satisfying the range API, which implicitly checks for it), but for the most part, you can just ignore it, it doesn't really make a big difference. Life goes on. T -- English has the lovely word "defenestrate", meaning "to execute by throwing someone out a window", or more recently "to remove Windows from a computer and replace it with something useful". :-) -- John Cowan
Jun 10 2020
next sibling parent Vinod K Chandran <kcvinu82 gmail.com> writes:
On Wednesday, 10 June 2020 at 21:41:54 UTC, H. S. Teoh wrote:

 It's stuck in limbo, like many things that people just cannot 
 agree on. There are a few places where it's needed (like 
 satisfying the range API, which implicitly checks for it), but 
 for the most part, you can just ignore it, it doesn't really 
 make a big difference.  Life goes on.


 T
H. S. Teoh, Yeah, got it.
Jun 10 2020
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 10 June 2020 at 21:41:54 UTC, H. S. Teoh wrote:
 There are a few places where it's needed (like satisfying the 
 range API, which implicitly checks for it)
That may have been true at one point, but it isn't true now: struct S { bool empty() { return false; } int front() { return 0; } void popFront() {} } static assert(isInputRange!S); // passes
Jun 10 2020
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jun 10, 2020 at 10:50:17PM +0000, Paul Backus via Digitalmars-d-learn
wrote:
 On Wednesday, 10 June 2020 at 21:41:54 UTC, H. S. Teoh wrote:
 There are a few places where it's needed (like satisfying the range
 API, which implicitly checks for it)
That may have been true at one point, but it isn't true now: struct S { bool empty() { return false; } int front() { return 0; } void popFront() {} } static assert(isInputRange!S); // passes
Nice. So pretty soon I can get rid of property spam from my code, which is really not very useful and only adds extra keystrokes for little benefit. T -- Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
Jun 10 2020
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 10 June 2020 at 22:50:17 UTC, Paul Backus wrote:
 static assert(isInputRange!S); // passes
isInputRange doesn't check it but others do. std.random.isSeedable requires property on front for example. Some apparently test incorrectly too, like std.range.primitives.moveFront seems to incorrectly reject front variables. property is done wrong and I wish they would fix it but right now it is... often ignorable but sometimes will do mysterious inconsistency due to library use.
Jun 10 2020
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 10 June 2020 at 23:03:21 UTC, Adam D. Ruppe wrote:
 On Wednesday, 10 June 2020 at 22:50:17 UTC, Paul Backus wrote:
 static assert(isInputRange!S); // passes
isInputRange doesn't check it but others do. std.random.isSeedable requires property on front for example.
Nope: struct S { bool empty() { return false; } int front() { return 0; } void popFront() {} enum bool isUniformRandom = true; void seed(int s) {} } static assert(isSeedable!(S, int));
Jun 10 2020
parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 10 June 2020 at 23:26:35 UTC, Paul Backus wrote:
 On Wednesday, 10 June 2020 at 23:03:21 UTC, Adam D. Ruppe wrote:
 On Wednesday, 10 June 2020 at 22:50:17 UTC, Paul Backus wrote:
 static assert(isInputRange!S); // passes
isInputRange doesn't check it but others do. std.random.isSeedable requires property on front for example.
Nope: struct S { bool empty() { return false; } int front() { return 0; } void popFront() {} enum bool isUniformRandom = true; void seed(int s) {} } static assert(isSeedable!(S, int));
My bad, missed the one-argument overload. That one does require property.
Jun 10 2020
prev sibling next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, June 10, 2020 3:41:54 PM MDT H. S. Teoh via Digitalmars-d-learn 
wrote:
 On Wed, Jun 10, 2020 at 08:24:19PM +0000, Vinod K Chandran via Digitalmars-
d-learn wrote:
 Hi all,
 I read in an old thread that authors of D wants to eliminate
  property. I just roughly read the big thread bu couldn't find a
 conclusion. After all that thread is a 48 page longer jumbo thread. So
 out of curiosity, i am asking this. What is the current state of
  property ? Is it deprecated ?
It's stuck in limbo, like many things that people just cannot agree on. There are a few places where it's needed (like satisfying the range API, which implicitly checks for it), but for the most part, you can just ignore it, it doesn't really make a big difference. Life goes on.
Yeah. There was a ton of arguing about what to do with it in the past, with the intention at one point being that property functions would always be called without parens, and all function without property would always be called with parens, but there was never full agreement on it, and once UFCS became widespread, the idea of requiring parens on non- property functions became a lot less popular, because many people don't like the idea of having empty runtime argument parens on a function call after the template argument parens - e.g. foo.map!(a => a * 42)() vs foo.map!(a => a * 42). Ultimately, property was never completed, and it's sort of just lingered on. As I understand it, property currently does exactly two things: 1. Become an attribute on the function which affects the mangling and can be queried my metaprogramming. IIRC, one result of this is that you can't overload a function that has property with one that doesn't. Most traits in Phobos do not check for property, but it's possible that some do. At one point, isForwardRange checked for it for save (which never made sense, since save doesn't act like a property), but that was removed. 2. Screw with the type of the function so that traits will mostly claim that its type is the return type of the function rather than a function that returns that type. This can cause some subtle and annoying problems with metaprogramming. Now, there is one ambiguity that property was supposed to solve that was never solved, and that's a property function that returns a callable. Right now, you're forced to use double parens (one set being the optional parens, and the other being the set to call the return value), whereas if it were truly treated as a property function, then the first set of parens would call the return value. As such, you can't really have a property function that returns a callable (whether property is used or not). So, even if we were to actually get rid of property, we might want to keep it for that case, but since it's never actually be made to fix that case, such a change would sadly be a breaking change. As things stand, property has no real practical purpose but frequently gets used to indicate that it's the intention of a function's author for it to be used as if it were a variable. I suspect that it's also frequently misunderstand that it's required if you want to call a function without parens. So, you're likely to see property in quite a lot of D code, but ultimately, all it's really doing is serving as documentation of the author's intent and screwing up metaprogramming. - Jonathan M Davis
Jun 10 2020
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jun 10, 2020 at 10:58:57PM -0600, Jonathan M Davis via
Digitalmars-d-learn wrote:
[...]
 As things stand,  property has no real practical purpose but
 frequently gets used to indicate that it's the intention of a
 function's author for it to be used as if it were a variable. I
 suspect that it's also frequently misunderstand that it's required if
 you want to call a function without parens. So, you're likely to see
  property in quite a lot of D code, but ultimately, all it's really
 doing is serving as documentation of the author's intent and screwing
 up metaprogramming.
[...] Ironically, just today I ran into this corner case where property actually became a solution to a real problem: //-----module1.d------ auto someGenericFunc(T)(T t) { ... static if (is(typeof(T.init.method) : T)) { R someRange = ...; // ElementType!R == T auto value = someRange.map!(e => e.method); } ... } //-----module2.d------ struct MyType { ... auto method()() { return ...; } ... } //------module3.d----- import module1; import module2; auto someFunc(...) { auto result = someGenericFunc!MyType; } This was failing compilation, because when MyType.method is a template, the static if condition in module1 fails. Adding property to MyType.method tells the compiler that `T.init.method` is intended to refer to the return value rather than the template function itself, and thus neatly solves the problem. T -- It's amazing how careful choice of punctuation can leave you hanging:
Jun 10 2020
parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 11 June 2020 at 05:41:25 UTC, H. S. Teoh wrote:
 Ironically, just today I ran into this corner case where 
  property actually became a solution to a real problem:

 	//-----module1.d------
 	auto someGenericFunc(T)(T t) {
 		...
 		static if (is(typeof(T.init.method) : T)) {
 			R someRange = ...; // ElementType!R == T
 			auto value = someRange.map!(e => e.method);
 		}
 		...
 	}
Personally I like the way Phobos does it: ReturnType!((T t) => t.method) This works for both property and non- property methods.
Jun 11 2020
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jun 11, 2020 at 10:46:32AM +0000, Paul Backus via Digitalmars-d-learn
wrote:
 On Thursday, 11 June 2020 at 05:41:25 UTC, H. S. Teoh wrote:
 
 Ironically, just today I ran into this corner case where  property
 actually became a solution to a real problem:
 
 	//-----module1.d------
 	auto someGenericFunc(T)(T t) {
 		...
 		static if (is(typeof(T.init.method) : T)) {
 			R someRange = ...; // ElementType!R == T
 			auto value = someRange.map!(e => e.method);
 		}
 		...
 	}
Personally I like the way Phobos does it: ReturnType!((T t) => t.method) This works for both property and non- property methods.
Mmm, very nice! I'll keep this in mind for next time! T -- The two rules of success: 1. Don't tell everything you know. -- YHL
Jun 12 2020