@property Incorrectly Implemented?

John via Digitalmars-d digitalmars-d at puremagic.com
Fri Sep 16 13:52:37 PDT 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:
>> 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.







More information about the Digitalmars-d mailing list