Talk:Property Discussion Wrap-up

From D Wiki
Revision as of 10:03, 26 January 2013 by Jpf (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
This is a talk page. It is to be used for discussion of potentially controversial or otherwise large changes to the article itself.
  • Please use the Add Topic link to start a discussion on a separate topic. Don't start a new topic inside an unrelated section, as it will only cause confusion.
  • As a rule, it is considered bad form to edit somebody else's comments. Instead, post your reply to their comments immediately after.
  • Please sign your comments with four tildes (~~~~) so that we know who said what.

ref returns and taking the address

ref T prop()

The current behavior without @property enforcement is that the setter function is called if there is one, else the reference to the return type is used.

prop = 4; // calls setter

If there is a setter property, but you want to bypass the setter, then

prop() = 4; // direct access to T ref

To limit @property ref retuns is a very harsh restriction to impose.

A solution is to allow

ref const(T) prop()

prop = 4; // calls setter

prop() = 4; // compile error

*(prop()) = 4; // compile error

What if you take the address of prop?

&prop returns the getter function address, but I'm not sure how to get the setter prop address.

&prop() returns the ref storage address. If return is const, you should be OK unless you do unsafe operations.

With @property enforcement, if we try to emulate storage addresses, then we'll have to disallow taking the address but that will significantly defeat the purpose of variable emulation. We can do something like this:

&prop returns the address of the setter function if there is one, else compiler error.

*(&prop) = 5; // calls the setter

Is the complexity of true variable emulation justified, or do we implement only partial variable emulation? But is enforcing variable emulation justified if we're to only partially implement? I would say we must either do full variable emulation, or not bother with it and treat the properties as regular functions.

RobT (talk) 22:37, 25 January 2013 (CET)

If you really want to go all-out, make &prop return a proxy object that implements opUnary!"*" so that *(&prop) = 5 will call the setter for prop. For example, the proxy object can be a struct whose opUnary!"*" returns a delegate that calls the setter. This is entirely within the current capabilities of D (that's how awesome D is!), minus perhaps some compiler support for actually lowering "&prop" to "return __proxyObj(...)".
I seriously doubt we need to go that far, though. I say just make it illegal to take the address of prop if it has a setter. If there's actually a real use case for such a construction, we can always have an address-getter variant of @property that lets the programmer return a proxy object from.—Quickfur (talk) 01:12, 26 January 2013 (CET)

Some unsorted thoughts: "taking the address but that will significantly defeat the purpose of variable emulation" is it really that bad? Every property which has a setter and returns a ref is a source for bugs. So we only have to consider ref returns if no setter is available. I wonder whether the frontend could do that optimization. Thinking of it, is this about performance or convenience(setter for free)? What does C# do? Can anyone come up with a real world example where you want to take the address of a property? And last but not least: Ref also allows to bypass the getter. If you don't have a getter and don't have a setter, you don't have a property. If you have one of those, returning ref is asking for bugs Jpf (talk)
ref const(T) @property prop() { return(T); } seems to work OK for the situations I tested. Maybe you can bypass the setter, but I think only by doing unsafe coding. RobT (talk)
But in that case your getter only returns the value directly. A compiler can easily optimize that without ref by inlining the property getter. Problems can occur if the getter does more advanced things, like incrementing a counter. Then the ref could be used to access the variable multiple times without incrementing the counter. I admit this can only happen with getters with side-effects which is bad style, but I fear ref will introduce corner cases where things break. Jpf (talk)