www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - property Incorrectly Implemented?

reply John <gyroheli gmail.com> writes:
Currently it seems that  property isn't implemented correctly. 
For some reason when you try to get the pointer of a property it 
returns a delegate for some reason. This just seems plain wrong, 
the whole purpose of a property is for a function to behave as if 
it weren't a function. There's also some inconsistencies in the 
behavior, "get" is implemented one way and then "set" is 
implemented another.

http://ideone.com/ZgGT2G

     &t.x         // returns "ref int delegate()"
     &t.x()       // ok returns "int*", but defeats purpose of 
 property
     &(t.j = 10)  // shouldn't this return "ref int delegate(int)" 
?

It would be nice to get this behavior fixed, so that it doesn't 
become set in stone. I think returning a delegate pointer is not 
what people would except nor is there really any use case for it.
Sep 06 2016
next sibling parent ag0aep6g <anonymous example.com> writes:
On 09/06/2016 09:18 PM, John wrote:
     &(t.j = 10)  // shouldn't this return "ref int delegate(int)" ?
`&t.j` should and does. With `= 10`, it's definitely a call, just like `&t.x()`.
 It would be nice to get this behavior fixed, so that it doesn't become
 set in stone.
Unfortunately, it already kinda is. Just flipping the switch would break circa all D code in existence. That's deemed unacceptable by the leadership, as far as I know. If this can even be fixed, it must be done very carefully. The -property compiler switch is currently being deprecated. Maybe it can be repurposed later on to change behavior to your liking. But that's at least a couple releases in the future, i.e. months, maybe years.
Sep 06 2016
prev sibling next sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tuesday, September 06, 2016 19:18:11 John via Digitalmars-d wrote:
 Currently it seems that  property isn't implemented correctly.
 For some reason when you try to get the pointer of a property it
 returns a delegate for some reason. This just seems plain wrong,
 the whole purpose of a property is for a function to behave as if
 it weren't a function. There's also some inconsistencies in the
 behavior, "get" is implemented one way and then "set" is
 implemented another.

 http://ideone.com/ZgGT2G

      &t.x         // returns "ref int delegate()"
      &t.x()       // ok returns "int*", but defeats purpose of
  property
      &(t.j = 10)  // shouldn't this return "ref int delegate(int)"
 ?

 It would be nice to get this behavior fixed, so that it doesn't
 become set in stone. I think returning a delegate pointer is not
 what people would except nor is there really any use case for it.
Okay. How would it work to safely get a pointer to anything but the property function when taking its address? &t.x() is just going to give you the address of the return value - which in most cases, is going to be a temporary, so if that even compiles in most cases, it's a bit scary. Sure, if the property function returns by ref, then it can work, but an property function which returns by ref isn't worth much, since you're then giving direct access to the member variable which is what an property function is usually meant to avoid. If you wanted to do that, you could just use a public member variable. So, given that most property functions are not going to return by ref, how does it make any sense at all for taking the address of an property function to do anything different than give you a delegate? Sure, that's not what happens when you take the address of a variable, but you're not dealing with a variable. You're dealing with an property function which is just trying to emulate a variable. The reality of the matter is that an property function is _not_ a variable. It's just trying to emulate one, and that abstraction falls apart _really_ fast once you try and do much beyond getting and setting the value - e.g. passing by ref falls flat on its face. We could do better than currently do (e.g. making += lower to code that uses both the getter and the setter when the getter doesn't return by ref), but there are some areas where a property function simply can't act like a variable, because it isn't one. There isn't even a guarantee that an property function is backed by memory. It could be a completely calculated value, in which case, expecting to get an address of a variable when taking the address of the property function makes even less sense. - Jonathan M Davis
Sep 06 2016
parent reply Kagamin <spam here.lot> writes:
On Tuesday, 6 September 2016 at 19:37:26 UTC, Jonathan M Davis 
wrote:
 but an  property function which returns by ref isn't worth 
 much, since you're then giving direct access to the member 
 variable which is what an  property function is usually meant 
 to avoid. If you wanted to do that, you could just use a public 
 member variable.
It can do lazy initialization, allow to set a breakpoint, log access etc.
 You're dealing with an  property function which is just trying 
 to emulate a variable.
That's the whole point. It's trying to emulate a variable, so why not make it do it?
Sep 07 2016
parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wednesday, September 07, 2016 08:15:43 Kagamin via Digitalmars-d wrote:
 On Tuesday, 6 September 2016 at 19:37:26 UTC, Jonathan M Davis

 wrote:
 but an  property function which returns by ref isn't worth
 much, since you're then giving direct access to the member
 variable which is what an  property function is usually meant
 to avoid. If you wanted to do that, you could just use a public
 member variable.
It can do lazy initialization, allow to set a breakpoint, log access etc.
But if you return the value by ref, then you pretty much circumvent all of that, because then someone can do something like take the address of the return value and procede to mutate it whenever they want without hitting your breakpoint or log messages or any of that. You can do a few things that can't be done with a public member variable, but on the whole, returning by ref defeats the purpose of having a property function. And there are plenty of property functions that don't even refer to variables but instead are calculated, in which case there is no variable to return a ref to anyway. So, while some property functions may return by ref, most won't, and it's arguably a bad idea in general.
 You're dealing with an  property function which is just trying
 to emulate a variable.
That's the whole point. It's trying to emulate a variable, so why not make it do it?
Because aside from a few basic operations, it's not possible. Stuff like assignment can be made to work, but something as simple as passing by ref falls simply cannot be done except in the case where the property function returns by ref - which is not the normal case. And for a large percentage of property functions, you don't want it to be the case that taking the address of the property function gives you a pointer to a member variable. There are certainly some operations that we could better emulate with property functions that currently don't work without returning by ref (like ++ or -=), but something like taking the address of the property function simply isn't going to work in most cases, and neither is passing by ref. Basically, only stuff that can be lowered to calls to the getter and setter property functions is going to work. Anything that would require an actual variable with an actual memory location isn't going to work unless the property function returns by ref, and making taking the address of that kind of property function give you the address of the variable would then not be consistent with any other property function, which would create a different set of problems. It's nice that we can have property syntax rather than having to have functions that start with get and set, but it really doesn't work to fully emulate variables. - Jonathan M Davis
Sep 07 2016
next sibling parent Lodovico Giaretta <lodovico giaretart.net> writes:
On Wednesday, 7 September 2016 at 09:34:12 UTC, Jonathan M Davis 
wrote:
 There are certainly some operations that we could better 
 emulate with  property functions that currently don't work 
 without returning by ref (like ++ or -=), but something like 
 taking the address of the  property function simply isn't going 
 to work in most cases, and neither is passing by ref. 
 Basically, only stuff that can be lowered to calls to the 
 getter and setter  property functions is going to work.

 It's nice that we can have property syntax rather than having 
 to have functions that start with get and set, but it really 
 doesn't work to fully emulate variables.

 - Jonathan M Davis
BTW, some time ago, in another thread [1] about properties, we ended up writing this wrapper [2], which does a pretty good job at simulating fields. In the original thread you can also find other variants of it. [1] http://forum.dlang.org/thread/okmgnrhdoeciovrfjmaj forum.dlang.org [2] http://pastebin.com/38n0fEtF
Sep 07 2016
prev sibling next sibling parent Meta <jared771 gmail.com> writes:
An easy way around this would be to disallow taking the address 
of a property at all. Sure it introduces a disparity between 
properties and real member variables, but that's surely worth all 
the confusion that might be caused otherwise. Is it even that 
common to take the address of a member variable of an aggregate 
outside low-level code?
Sep 07 2016
prev sibling parent Kagamin <spam here.lot> writes:
On Wednesday, 7 September 2016 at 09:34:12 UTC, Jonathan M Davis 
wrote:
 But if you return the value by ref, then you pretty much 
 circumvent all of that, because then someone can do something 
 like take the address of the return value and procede to mutate 
 it whenever they want without hitting your breakpoint or log 
 messages or any of that. You can do a few things that can't be 
 done with a public member variable, but on the whole, returning 
 by ref defeats the purpose of having a property function.
No, manipulation of the value can be only done after accessing it through the property, thus its mission is fulfilled.
 So, while some  property functions may return by ref, most 
 won't, and it's arguably a bad idea in general.
It's good when it allows easy refactoring.
 Stuff like assignment can be made to work, but something as 
 simple as passing by ref falls simply cannot be done except in 
 the case where the  property function returns by ref
True.
 And for a large percentage of property functions, you don't 
 want it to be the case that taking the address of the property 
 function gives you a pointer to a member variable.
It depends.
 Anything that would require an actual variable with an actual 
 memory location isn't going to work unless the  property 
 function returns by ref, and making taking the address of that 
 kind of  property function give you the address of the variable 
 would then not be consistent with any other  property function, 
 which would create a different set of problems.
Properties are meant to be inconsistent, i.e. to have different implementations.
 It's nice that we can have property syntax rather than having 
 to have functions that start with get and set, but it really 
 doesn't work to fully emulate variables.
What you said is more like your preference to not pass values by ref. If you don't want it, don't do it, no problem.
Sep 08 2016
prev sibling next sibling parent Lodovico Giaretta <lodovico giaretart.net> writes:
On Tuesday, 6 September 2016 at 19:18:11 UTC, John wrote:
 Currently it seems that  property isn't implemented correctly. 
 For some reason when you try to get the pointer of a property 
 it returns a delegate for some reason. This just seems plain 
 wrong, the whole purpose of a property is for a function to 
 behave as if it weren't a function. There's also some 
 inconsistencies in the behavior, "get" is implemented one way 
 and then "set" is implemented another.

 http://ideone.com/ZgGT2G

     &t.x         // returns "ref int delegate()"
     &t.x()       // ok returns "int*", but defeats purpose of 
  property
     &(t.j = 10)  // shouldn't this return "ref int 
 delegate(int)" ?

 It would be nice to get this behavior fixed, so that it doesn't 
 become set in stone. I think returning a delegate pointer is 
 not what people would except nor is there really any use case 
 for it.
With properties, the & operator is the only way to have the function itself and not it's return value. The reason is that the return value of a function is not necessarily an lvalue, so taking its address is not always correct. Imagine this: property int x() { return 3; } As 3 is an rvalue, you cannot take its address. That's the difference between a true field and a computed one. The purpose of properties is the following: struct S { property int x() { /* whatever */ } int y() { /* whatever */ } } writeln(typeof(S.x).stringof); // prints int writeln(typeof(S.y).stringof); // prints int delegate()
Sep 06 2016
prev sibling next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/6/16 3:18 PM, John wrote:
 Currently it seems that  property isn't implemented correctly. For some
 reason when you try to get the pointer of a property it returns a
 delegate for some reason. This just seems plain wrong, the whole purpose
 of a property is for a function to behave as if it weren't a function.
 There's also some inconsistencies in the behavior, "get" is implemented
 one way and then "set" is implemented another.

 http://ideone.com/ZgGT2G

     &t.x         // returns "ref int delegate()"
     &t.x()       // ok returns "int*", but defeats purpose of  property
     &(t.j = 10)  // shouldn't this return "ref int delegate(int)" ?

 It would be nice to get this behavior fixed, so that it doesn't become
 set in stone. I think returning a delegate pointer is not what people
 would except nor is there really any use case for it.
Just FYI, at the moment I believe the only difference (aside from the defunct -property switch) between a property function and a non- property function is: int foo1() { return 1; } property int foo2() { return 1; } pragma(msg, typeof(foo1)); // int function() pragma(msg, typeof(foo2)); // int That's it. typeof returns a different thing. All property functions act just like normal functions when used in all other cases, and property syntax (assignment and getting) work on non- property functions. This situation is less than ideal. But it's been battled about dozens of times on the forums (including the very reasonable points you are making). It hasn't been solved, and the cynic in me says it won't ever be. -Steve
Sep 06 2016
prev sibling next sibling parent reply Ethan Watson <gooberman gmail.com> writes:
On Tuesday, 6 September 2016 at 19:18:11 UTC, John wrote:
 It would be nice to get this behavior fixed.
Disagree. I've used properties before in C# to transform to and from data sets required for network multiplayer. It works functionally the same way in D. Behaviour is as I would expect for the wider implications of how properties can work.
Sep 07 2016
parent reply John <gyroheli gmail.com> writes:
On Tuesday, 6 September 2016 at 19:37:26 UTC, Jonathan M Davis 
wrote:
 On Tuesday, September 06, 2016 19:18:11 John via Digitalmars-d 
 wrote:
 Currently it seems that  property isn't implemented correctly. 
 For some reason when you try to get the pointer of a property 
 it returns a delegate for some reason. This just seems plain 
 wrong, the whole purpose of a property is for a function to 
 behave as if it weren't a function. There's also some 
 inconsistencies in the behavior, "get" is implemented one way 
 and then "set" is implemented another.

 http://ideone.com/ZgGT2G

      &t.x         // returns "ref int delegate()"
      &t.x()       // ok returns "int*", but defeats purpose of
  property
      &(t.j = 10)  // shouldn't this return "ref int 
 delegate(int)"
 ?

 It would be nice to get this behavior fixed, so that it 
 doesn't become set in stone. I think returning a delegate 
 pointer is not what people would except nor is there really 
 any use case for it.
Okay. How would it work to safely get a pointer to anything but the property function when taking its address? &t.x() is just going to give you the address of the return value - which in most cases, is going to be a temporary, so if that even compiles in most cases, it's a bit scary. Sure, if the property function returns by ref, then it can work, but an property function which returns by ref isn't worth much, since you're then giving direct access to the member variable which is what an property function is usually meant to avoid. If you wanted to do that, you could just use a public member variable. So, given that most property functions are not going to return by ref, how does it make any sense at all for taking the address of an property function to do anything different than give you a delegate? Sure, that's not what happens when you take the address of a variable, but you're not dealing with a variable. You're dealing with an property function which is just trying to emulate a variable. The reality of the matter is that an property function is _not_ a variable. It's just trying to emulate one, and that abstraction falls apart _really_ fast once you try and do much beyond getting and setting the value - e.g. passing by ref falls flat on its face. We could do better than currently do (e.g. making += lower to code that uses both the getter and the setter when the getter doesn't return by ref), but there are some areas where a property function simply can't act like a variable, because it isn't one. There isn't even a guarantee that an property function is backed by memory. It could be a completely calculated value, in which case, expecting to get an address of a variable when taking the address of the property function makes even less sense. - Jonathan M Davis
I don't see how that would be a problem, you can't take the address of an rvalue... The problem you describe would be true for functions as well. What's not true is that it is compilable (see: http://ideone.com/MXhkXC ). Any problem you can conjure up about references, temporary values and pointers, all of that would be true for a regular function as well. Obviously it is not a variable, but if you use a function and it returns a reference and you take the address of it. What you get is the address of the returned value not of the function. int v = obj.prop; if you look at that "prop" is a called function pretending to be a variable. If you take the address of a called function, you get the address of the returned variable, not the function. If you take the address of a variable, you get the address of the variable. On Wednesday, 7 September 2016 at 07:44:05 UTC, Ethan Watson wrote:
 On Tuesday, 6 September 2016 at 19:18:11 UTC, John wrote:
 It would be nice to get this behavior fixed.
Disagree. I've used properties before in C# to transform to and from data sets required for network multiplayer. It works functionally the same way in D. Behaviour is as I would expect for the wider implications of how properties can work.
You can't really take one sentence out of context, I didn't say it in the sense that it was completely broken to the point of being useless. The part I'm asking to be changed, you probably didn't even ever use. C# is a managed language, I don't think you can even take the pointer of anything unless you enable the unsafe switch. On Tuesday, 6 September 2016 at 19:34:59 UTC, ag0aep6g wrote:
 On 09/06/2016 09:18 PM, John wrote:
     &(t.j = 10)  // shouldn't this return "ref int 
 delegate(int)" ?
`&t.j` should and does. With `= 10`, it's definitely a call, just like `&t.x()`.
 It would be nice to get this behavior fixed, so that it 
 doesn't become
 set in stone.
Unfortunately, it already kinda is. Just flipping the switch would break circa all D code in existence. That's deemed unacceptable by the leadership, as far as I know.
Don't really see that to be true. I don't see any use case for taking the address of the delegate for a property. Wouldn't be surprised if it only broke 1% of code out there. I mean it's probably used so little that it isn't even properly implemented. You can get the getter property delegate, but you can't get the setter property delegate. Either way it's broken as it is now.
Sep 11 2016
parent reply Ethan Watson <gooberman gmail.com> writes:
On Sunday, 11 September 2016 at 07:19:54 UTC, John wrote:
 You can't really take one sentence out of context, I didn't say 
 it in the sense that it was completely broken to the point of 
 being useless.
There's nothing out of context about it. Would it have made you feel better had I quoted your entire message knowing that I wouldn't have changed a word of the response? But if that's how you want to play.
 The part I'm asking to be changed, you probably didn't even 
 ever use. C# is a managed language, I don't think you can even 
 take the pointer of anything unless you enable the unsafe 
 switch.
You're not showing a good grasp at all as to what a property is. In C# and in D, a property has *never* guaranteed the existence of a variable. In both cases, they allow syntactic sugar for letting the getter/setter pattern established by C++ look like variables. This is important. No, really. Take std.bitmanip for an example of what I was talking about. It autogenerates properties for a bitfield. The types each property returns and lets you set are not at all indicative of the datatype underneath as it's literally just a bunch of bits. The property functions transform the data types given/return to/from a bitfield. What exactly do you suggest &property return if it was to return a char starting at bit 13 of a bitfield? But we can go one further. __traits( allMembers, Type ) and __traits( getMember, Type ). Let's say you're writing an auto-serialisation library (or take std.json as an example). Assuming a property is a stand-in for another variable then what happens there when you're checking for the type of a member is the delegate type, and later on you'll get the actual variable. Now change it so that the type of a property returns the actual type. Now you're serialising a piece of data twice. But what if our property function increments another variable inside a class whenever you access it? That's pretty dangerous if you start treating the property as an actual type instead of a function/delegate. Thus, your example: &t.x // returns "ref int delegate()" &t.x() // ok returns "int*", but defeats purpose of property &(t.j = 10) // shouldn't this return "ref int delegate(int)" ? First one I'd expect. Second one I'd expect. Third one I'd expect results in int*. You're getting the address of the results of the assign operation. Look at it this way: int val = (t.j = 10); You'd expect val and t.j to be 10, right? So why do you expect to get a ref int delegate(int) just because you ask for the address of it? Like I said. Disagree. There's nothing that needs fixing here.
Sep 11 2016
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 11.09.2016 14:02, Ethan Watson wrote:
 On Sunday, 11 September 2016 at 07:19:54 UTC, John wrote:
 ...
 The part I'm asking to be changed, you probably didn't even ever use.
 C# is a managed language, I don't think you can even take the pointer
 of anything unless you enable the unsafe switch.
... In C# and in D, a property has *never* guaranteed the existence of a variable. In both cases, they allow syntactic sugar for letting the getter/setter pattern established by C++ look like variables. ...
His property returns by ref.
 ...

 Take std.bitmanip for an example of what I was talking about. It
 autogenerates properties for a bitfield. The types each property returns
 and lets you set are not at all indicative of the datatype underneath as
 it's literally just a bunch of bits. The property functions transform
 the data types given/return to/from a bitfield. What exactly do you
 suggest &property return if it was to return a char starting at bit 13
 of a bitfield?
 ...
Not a delegate. In a sane world, it would give you a compile error because 'property' is an rvalue.
 But we can go one further. __traits( allMembers, Type ) and __traits(
 getMember, Type ). Let's say you're writing an auto-serialisation
 library (or take std.json as an example). Assuming a property is a
 stand-in for another variable then what happens there when you're
 checking for the type of a member is the delegate type, and later on
 you'll get the actual variable. Now change it so that the type of a
 property returns the actual type. Now you're serialising a piece of data
 twice.
 ...
You do realize that typeof(property) is the type of the return value, right? Also, it's easy. Add __traits(isVariable,...) or __traits(isProperty,...), or just use .tupleof. Furthermore you can even get the property accessor function overload set using (a hypothetical) __traits(getPropertyAccessors,...).
 But what if our  property function increments another variable inside a
 class whenever you access it? That's pretty dangerous if you start
 treating the property as an actual type instead of a function/delegate.

 Thus, your example:

     &t.x         // returns "ref int delegate()"
     &t.x()       // ok returns "int*", but defeats purpose of  property
     &(t.j = 10)  // shouldn't this return "ref int delegate(int)" ?

 First one I'd expect.
Why? It's awful.
 Second one I'd expect.
No, even more awful. typeof(t.x) is 'int'. You are not even supposed to be able to call an 'int'. The second one should be a compile error: "Error: function expected before (), not t.x of type int"
 Third one I'd expect results in int*.
Agreed, that one is sane.
Sep 11 2016
parent Ethan Watson <gooberman gmail.com> writes:
On Sunday, 11 September 2016 at 23:31:54 UTC, Timon Gehr wrote:
 His property returns by ref.
Irrelevant for the implementation details of properties. Ref in that context specifies a function property that makes the property function return by ref (wrap your head around that one). That entire post went in to detail about why treating properties as the functions they are is correct.
 You do realize that typeof(property) is the type of the return 
 value, right? Also, it's easy. Add __traits(isVariable,...) or 
 __traits(isProperty,...), or just use .tupleof. Furthermore you 
 can even get the property accessor function overload set using 
 (a hypothetical) __traits(getPropertyAccessors,...).
You are correct. typeof( __traits( getMember, Type, PropertyName ) ) is the type of the return type of the function, since getMember forms a complete expression which evaluates down to the return type. Note that all of the __traits( is<X>Function ) return true correctly on these things though. This is one of the checks I have to make when parsing over a class to correctly determine what is and isn't actually a variable. I've even wrapped it all up in a trait called IsVariable. The std library has traits for checking types but nothing that straight up tells you if something is a variable or not. As such, who needs __traits( getPropertyAccessors ) when __traits( getOverloads ) already works?
 [Commentary on example]
Actually, I take back what I said. Mostly because of typeof( t.x ). The thing that needs fixing is the property evaluation order so that ambiguities like all of this don't exist.
Sep 12 2016
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
On Sunday, 11 September 2016 at 12:02:29 UTC, Ethan Watson wrote:
 But what if our  property function increments another variable 
 inside a class whenever you access it? That's pretty dangerous 
 if you start treating the property as an actual type instead of 
 a function/delegate.
You mean your serialization library will break if property changes behavior?
Sep 12 2016
parent reply Ethan Watson <gooberman gmail.com> writes:
On Monday, 12 September 2016 at 09:25:40 UTC, Kagamin wrote:
 You mean your serialization library will break if  property 
 changes behavior?
Any serialisation library can break if a property is indistinguishable from an ordinary type, as a property is explicitly code that returns a value and faces all the allowances and restrictions that normal functions have. In my case, it will break if this template fails: template IsVariable( X... ) if ( X.length == 1 ) { static if( is( X[ 0 ] == void ) || is( typeof( X[ 0 ] ) == void ) ) { enum IsVariable = false; } else static if ( !IsSomeType!( X[ 0 ] ) ) { static if( isSomeFunction!( X[ 0 ] ) ) { enum IsVariable = isFunctionPointer!( X[ 0 ] ) || isDelegate!( X[ 0 ] ); } else { enum IsVariable = is( typeof( X [ 0 ] ) ) && !is( typeof( X [ 0 ] ) == void ) && IsMutable!( typeof( X[ 0 ] ) ); } } else { enum IsVariable = false; } }
Sep 12 2016
parent Kagamin <spam here.lot> writes:
Your template will not change behavior if isSomeFunction returns 
true for properties. That's probably ok.
Sep 12 2016
prev sibling parent reply John <gyroheli gmail.com> writes:
On Sunday, 11 September 2016 at 12:02:29 UTC, Ethan Watson wrote:
 On Sunday, 11 September 2016 at 07:19:54 UTC, John wrote:
 You can't really take one sentence out of context, I didn't 
 say it in the sense that it was completely broken to the point 
 of being useless.
There's nothing out of context about it. Would it have made you feel better had I quoted your entire message knowing that I wouldn't have changed a word of the response? But if that's how you want to play.
Your comment was out of place, saying properties don't need to be changed is like saying property shouldn't even be a D feature cause you can create the same functional program in C++, which does not have the property feature. You also made a reference to C#, which doesn't even allow you take address of So I don't know what you mean by that's how I want to play, when you instigated said argument.
 The part I'm asking to be changed, you probably didn't even 
 ever use. C# is a managed language, I don't think you can even 
 take the pointer of anything unless you enable the unsafe 
 switch.
You're not showing a good grasp at all as to what a property is. In C# and in D, a property has *never* guaranteed the existence of a variable. In both cases, they allow syntactic sugar for letting the getter/setter pattern established by C++ look like variables. This is important. No, really. Take std.bitmanip for an example of what I was talking about. It autogenerates properties for a bitfield. The types each property returns and lets you set are not at all indicative of the datatype underneath as it's literally just a bunch of bits. The property functions transform the data types given/return to/from a bitfield. What exactly do you suggest &property return if it was to return a char starting at bit 13 of a bitfield?
It's not really that important. What it allows is returning references. You can make a comparison to any other language that has properties it doesn't really matter. This is how D was implemented. If they wanted to be like every other language then it shouldn't have been allowed to even return a reference. But it is does, that's how it's implemented and odds are it probably won't change now to not allow it. D also has the "&" implemented, what I am discussing is whether it was implemented correctly or not. Honestly it is no implemented correctly. To the point I would actually rather they remove the functionality so that you can't take the address of a property. If they are not willing to change it to function in a different way. This has been brought up by someone else. I honestly don't understand why it's such a hard concept. Maybe you don't come from C++ and thus don't use a language that provides a way to take the address of things. That's why it keeps being brought up. Anyways a bitfield can't actually represent a single, there's no type for a bit. The smallest type is a byte, which is 8 bits. So even if it wasn't a property there's no way you can take the address of a bit. So that's the first issue, you are trying to use an example that doesn't make sense even outside the concept of properties. The second issue is, this is defined behavior. You can't take the address of a rvalue, there's an ideone link in my previous post show this if you missed it. So taking the address of a property would return an error if it didn't return a reference.
 But we can go one further. __traits( allMembers, Type ) and 
 __traits( getMember, Type ). Let's say you're writing an 
 auto-serialisation library (or take std.json as an example). 
 Assuming a property is a stand-in for another variable then 
 what happens there when you're checking for the type of a 
 member is the delegate type, and later on you'll get the actual 
 variable. Now change it so that the type of a property returns 
 the actual type. Now you're serialising a piece of data twice.

 But what if our  property function increments another variable 
 inside a class whenever you access it? That's pretty dangerous 
 if you start treating the property as an actual type instead of 
 a function/delegate.
Well that's how it is currently implemented actually. struct S { property int prop() { return 0; } } writeln(typeof(S.prop).stringof) // prints "int", not "delegate" I'm only talking about taking the address of a property. That does no way infer that there shouldn't be some way to identify that it is a property at compile time. The way you should check if a member is a property shouldn't be by taking the address of it. That's not as clear as having a trait or other implementation such that you could do "isProperty". That is much more clearer. If the only way to identify a property is by checking the typeof() a member for when you take it's address, then that's a hack and a better way to identify a property should be implemented.
 Thus, your example:

     &t.x         // returns "ref int delegate()"
     &t.x()       // ok returns "int*", but defeats purpose of 
  property
     &(t.j = 10)  // shouldn't this return "ref int 
 delegate(int)" ?

 First one I'd expect. Second one I'd expect. Third one I'd 
 expect results in int*. You're getting the address of the 
 results of the assign operation. Look at it this way: int val = 
 (t.j = 10); You'd expect val and t.j to be 10, right? So why do 
 you expect to get a ref int delegate(int) just because you ask 
 for the address of it?
Well I put that there more satirically, as as far as I am aware there is no way to get the delegate for the setter. Getting the delegate from t.x would make as much sense as it does for that setter function.
Sep 16 2016
next sibling parent Chris Wright <dhasenan gmail.com> writes:
On Fri, 16 Sep 2016 20:52:37 +0000, John wrote:
 You also made a reference to C#, which doesn't even
 allow you take address of So I don't know what you mean by that's how I
 want to play, when you instigated said argument.
C# allows you to use pointers and take the address of fields. You must compile your code with `/unsafe` and use an `unsafe {}` block to do it. It does not allow you to take the address of a property. It complains: "Cannot take the address of the given expression".
 as far as I am aware there is no way to get the delegate for the setter.
Let's consider the following type: struct Foo { property int a() { return 1; } property int a(int v) { return v; } } Given an instance `Foo f`, `f.a` is an overload set. It's a bundle of several functions that can be referred to using the same symbols and must be disambiguated. Most of the time, you disambiguate by calling the function with arguments. However, that is not the only way: when taking the address of a function, the compiler looks at the static type that the expression is expected to return. So the following works: int delegate(int) setter = &f.a; int delegate() getter = &f.a; But this doesn't: auto dg = &f.a; // Error: cannot infer type from overloaded function symbol &f.a The same principle applies for any overloaded functions.
 The way you should check if a member is a property shouldn't be by
 taking the address of it.
Check if __traits(getOverloads) for the member name has at least one overload. Or __traits(getVirtualFunctions) and see if there's a matching name. Unfortunately, std.traits doesn't have anything already implemented to do this. You may want to test things out and check the specific compiler error messages before declaring that they don't work. They can be rather dense, though.
Sep 16 2016
prev sibling parent reply Ethan Watson <gooberman gmail.com> writes:
On Friday, 16 September 2016 at 20:52:37 UTC, John wrote:
 Your comment was out of place, saying properties don't need to 
 be changed is like saying  property shouldn't even be a D 
 feature cause you can create the same functional program in 
 C++, which does not have the property feature.
Stop reading rubbish that isn't there. And pay attention. MSVC has the __declspec( property ) extension.
 You also made a reference to C#, which doesn't even allow you 
 take address of
And? Properties in C# are a massive example of a comparable feature where executed code is syntactically treated in some ways to a variable.
 So I don't know what you mean by that's how I want to play, 
 when you instigated said argument.
I indicated you're taking it personally. Which you are.
 It's not really that important. What it allows is returning 
 references. You can make a comparison to any other language 
 that has properties it doesn't really matter. This is how D was 
 implemented. If they wanted to be like every other language 
 then it shouldn't have been allowed to even return a reference. 
 But it is does, that's how it's implemented and odds are it 
 probably won't change now to not allow it. D also has the "&" 
 implemented, what I am discussing is whether it was implemented 
 correctly or not. Honestly it is no implemented correctly. To 
 the point I would actually rather they remove the functionality 
 so that you can't take the address of a property. If they are 
 not willing to change it to function in a different way.
Taking the address of a property and getting a function type is important. Did you know that this C++ class: class SomeObject { virtual int getSomeValue() const; virtual int setSomeValue( int value ); }; Matches up exactly to this D class: extern( C++ ) class SomeObject { property SomeValue() const; property SomeValue( int value ); }
 This has been brought up by someone else. I honestly don't 
 understand why it's such a hard concept.
Because your understanding of the technical details is limited...
 Maybe you don't come from C++ and thus don't use a language 
 that provides a way to take the address of things.
...and you're assuming you know more than what I do on the subject.
 That's why it keeps being brought up.
Calm down.
 Anyways a bitfield can't actually represent a single, there's 
 no type for a bit. The smallest type is a byte, which is 8 
 bits. So even if it wasn't a property there's no way you can 
 take the address of a bit. So that's the first issue, you are 
 trying to use an example that doesn't make sense even outside 
 the concept of properties. The second issue is, this is defined 
 behavior. You can't take the address of a rvalue, there's an 
 ideone link in my previous post show this if you missed it. So 
 taking the address of a property would return an error if it 
 didn't return a reference.
What you're suggesting, and why I brought up the example, is to change the implementation details of properties for *one* use case. This has wide ranging implications that you've clearly not thought of. Like if I was to take the address of that property for the purposes of exposing a function to C++. You want to make it so I don't get that function? Or that there's some extra convoluted method of getting it solely because you think a property should be something that it's not?
 Well that's how it is currently implemented actually.

     struct S
     {
          property int prop() { return 0; }
     }

     writeln(typeof(S.prop).stringof) // prints "int", not 
 "delegate"
Read further. I have suggested that the property resolution order gets changed so that this ambiguity goes away.
 blah blah blah
Yeah I covered everything else already. Not helping your cause by stating your example that started this topic was *satirical*.
Sep 17 2016
parent John <gyroheli gmail.com> writes:
On Saturday, 17 September 2016 at 10:55:59 UTC, Ethan Watson 
wrote:
 On Friday, 16 September 2016 at 20:52:37 UTC, John wrote:
 Your comment was out of place, saying properties don't need to 
 be changed is like saying  property shouldn't even be a D 
 feature cause you can create the same functional program in 
 C++, which does not have the property feature.
Stop reading rubbish that isn't there. And pay attention. MSVC has the __declspec( property ) extension.
MSVC != C++ I'm not going to pay attention to a feature that isn't standard and only Microsoft's compiler seems to have. Since you brought it up though, it's a good chance to look at how it behaves. struct Test { int p; int& prop() { return p; } __declspec(property(get = prop, put = prop)) int& magic; }; void main() { Test test; test.p = 10; if(&test.p == &test.magic) { std::cout << &test.p << '\n' << &test.magic << '\n' << "magic"; } } I'll give you a hint, it prints magic. Imagine that.
 You also made a reference to C#, which doesn't even allow you 
 take address of
And? Properties in C# are a massive example of a comparable feature where executed code is syntactically treated in some ways to a variable.
Yes, you can't take the address of a property in C#, with or without unsafe on.
 So I don't know what you mean by that's how I want to play, 
 when you instigated said argument.
I indicated you're taking it personally. Which you are.
I wasn't until you indicated that you were taking it personally with that statement.
 It's not really that important. What it allows is returning 
 references. You can make a comparison to any other language 
 that has properties it doesn't really matter. This is how D 
 was implemented. If they wanted to be like every other 
 language then it shouldn't have been allowed to even return a 
 reference. But it is does, that's how it's implemented and 
 odds are it probably won't change now to not allow it. D also 
 has the "&" implemented, what I am discussing is whether it 
 was implemented correctly or not. Honestly it is no 
 implemented correctly. To the point I would actually rather 
 they remove the functionality so that you can't take the 
 address of a property. If they are not willing to change it to 
 function in a different way.
Taking the address of a property and getting a function type is important. Did you know that this C++ class: class SomeObject { virtual int getSomeValue() const; virtual int setSomeValue( int value ); }; Matches up exactly to this D class: extern( C++ ) class SomeObject { property SomeValue() const; property SomeValue( int value ); }
You have "get" and "set" in the C++ function, so no it doesn't match it exactly. Semantics aside, you shouldn't be referencing behavior of properties in a language that doesn't even have properties. It's simply a way to emulate properties. If C++ had properties, I would imagine they would behave like the above MSVC implementation does. Shouldn't be held back by C++ for such a reason, you can easily take off those property attributes and that would probably be the saner solution. So that it actually functions the same, in that you need the use the paranethese to set and get the variable. That aside I doubt you ever take the pointer of those getters and setters in C++ either.
 Anyways a bitfield can't actually represent a single, there's 
 no type for a bit. The smallest type is a byte, which is 8 
 bits. So even if it wasn't a property there's no way you can 
 take the address of a bit. So that's the first issue, you are 
 trying to use an example that doesn't make sense even outside 
 the concept of properties. The second issue is, this is 
 defined behavior. You can't take the address of a rvalue, 
 there's an ideone link in my previous post show this if you 
 missed it. So taking the address of a property would return an 
 error if it didn't return a reference.
What you're suggesting, and why I brought up the example, is to change the implementation details of properties for *one* use case. This has wide ranging implications that you've clearly not thought of. Like if I was to take the address of that property for the purposes of exposing a function to C++. You want to make it so I don't get that function? Or that there's some extra convoluted method of getting it solely because you think a property should be something that it's not?
One use case is better than the zero use case it current holds.. And using it to identify whether a member is a property is a misuse and i'd actually count that as a negative. So negative one use case.
 Well that's how it is currently implemented actually.

     struct S
     {
          property int prop() { return 0; }
     }

     writeln(typeof(S.prop).stringof) // prints "int", not 
 "delegate"
Read further. I have suggested that the property resolution order gets changed so that this ambiguity goes away.
 blah blah blah
Yeah I covered everything else already. Not helping your cause by stating your example that started this topic was *satirical*.
Alright then "blah blah blah" as you try to misdirect from all the points that were made that you can't create a counter argument for.
Sep 24 2016
prev sibling parent Gary Willoughby <dev nomad.so> writes:
On Tuesday, 6 September 2016 at 19:18:11 UTC, John wrote:

This is all you need to know:

https://wiki.dlang.org/Property_Discussion_Wrap-up
Sep 12 2016