digitalmars.D - property Incorrectly Implemented?
- John (16/16) Sep 06 2016 Currently it seems that @property isn't implemented correctly.
- ag0aep6g (10/13) Sep 06 2016 `&t.j` should and does. With `= 10`, it's definitely a call, just like
- Jonathan M Davis via Digitalmars-d (28/44) Sep 06 2016 Okay. How would it work to safely get a pointer to anything but the
- Kagamin (6/13) Sep 07 2016 It can do lazy initialization, allow to set a breakpoint, log
- Jonathan M Davis via Digitalmars-d (32/45) Sep 07 2016 But if you return the value by ref, then you pretty much circumvent all ...
- Lodovico Giaretta (9/20) Sep 07 2016 BTW, some time ago, in another thread [1] about properties, we
- Meta (6/6) Sep 07 2016 An easy way around this would be to disallow taking the address
- Kagamin (11/35) Sep 08 2016 No, manipulation of the value can be only done after accessing it
- Lodovico Giaretta (16/33) Sep 06 2016 With properties, the & operator is the only way to have the
- Steven Schveighoffer (15/28) Sep 06 2016 Just FYI, at the moment I believe the only difference (aside from the
- Ethan Watson (5/6) Sep 07 2016 Disagree. I've used properties before in C# to transform to and
- John (31/102) Sep 11 2016 I don't see how that would be a problem, you can't take the
- Ethan Watson (44/51) Sep 11 2016 There's nothing out of context about it. Would it have made you
- Timon Gehr (14/52) Sep 11 2016 Not a delegate. In a sane world, it would give you a compile error
- Ethan Watson (22/29) Sep 12 2016 Irrelevant for the implementation details of properties. Ref in
- Kagamin (3/7) Sep 12 2016 You mean your serialization library will break if @property
- Ethan Watson (32/34) Sep 12 2016 Any serialisation library can break if a property is
- Kagamin (2/2) Sep 12 2016 Your template will not change behavior if isSomeFunction returns
- John (55/106) Sep 16 2016 Your comment was out of place, saying properties don't need to be
- Chris Wright (32/38) Sep 16 2016 C# allows you to use pointers and take the address of fields. You must
- Ethan Watson (37/80) Sep 17 2016 Stop reading rubbish that isn't there.
- John (49/124) Sep 24 2016 MSVC != C++
- Gary Willoughby (3/3) Sep 12 2016 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.
Sep 06 2016
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
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
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
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 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.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.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 DavisYou'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
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 DavisBTW, 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
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
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 refTrue.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
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
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
On Tuesday, 6 September 2016 at 19:18:11 UTC, John wrote:It would be nice to get this behavior fixed.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
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: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: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 DavisOn Tuesday, 6 September 2016 at 19:18:11 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. The part I'm asking to be changed, you probably 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:It would be nice to get this behavior fixed.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.On 09/06/2016 09:18 PM, John wrote: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.&(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.
Sep 11 2016
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 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. 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
On 11.09.2016 14:02, Ethan Watson wrote:On Sunday, 11 September 2016 at 07:19:54 UTC, John wrote:His property returns by ref.... The part I'm asking to be changed, you probably didn't even ever use. of anything unless you enable the unsafe switch.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. ...... 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
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
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
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
Your template will not change behavior if isSomeFunction returns true for properties. That's probably ok.
Sep 12 2016
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: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 what you mean by that's how I want to play, when you instigated said argument.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.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.The part I'm asking to be changed, you probably didn't 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 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.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
On Fri, 16 Sep 2016 20:52:37 +0000, John wrote: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.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
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.take address offeature 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 blahYeah I covered everything else already. Not helping your cause by stating your example that started this topic was *satirical*.
Sep 17 2016
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: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.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.without unsafe on.take address offeature where executed code is syntactically treated in some ways to a variable.I wasn't until you indicated that you were taking it personally with that statement.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.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.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 ); }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.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?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.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 blahYeah I covered everything else already. Not helping your cause by stating your example that started this topic was *satirical*.
Sep 24 2016
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