Taking address of properties

Robert jfanatiker at gmx.at
Sun Feb 10 08:52:47 PST 2013


On Sun, 2013-02-10 at 10:43 -0500, Steven Schveighoffer wrote:
> On Sun, 10 Feb 2013 07:09:52 -0500, Robert <jfanatiker at gmx.at> wrote:
> 
> > Ok, at the very first I have to make clear that my DIP is about changing
> > the actual specification, not trying to make the implementation to match
> > the specification, because in my view of things, the specification is
> > the problem.
> >
> > Properties in my proposal are no longer about optional parentheses ore
> > forbidden parentheses. Properties are a concept hat benefits from the
> > fact, that parentheses are optional, but would work either way.
> 
> We don't need a feature to implement encapsulation, it's quite possible  
> without property specification.  And your proposal does not guarantee  
> encapsulation anyway.

We don't need it. -> Yes.
Would it be nice to have. -> Discuss-able.
Does it solve the issues we have. -> Yes.
Properties as such do guarantee encapsulation, if you access the fields
through the property methods. There is no way to forbid the programmer
to break it by other members, alias this, or what ever. But as you said
D is a systems programming language.

> 
> Then why do we need special syntax?  I don't see the point.  This is just  
> back to D1 properties.
Actually only two hard requirements:
1. Downwards-Compatibility with functions returning ref. (Downwards
means that you can replace a property with a function returning ref, but
not the other way round)
2. Backwards compatibility.

Not mandatory:
3. Nice syntax

Why do we need properties to be radically different than functions? This
breaks templates, except we try to make almost everything a property,
what DIP23 seems to do. All I do is strive for a clean concept what a
property actually is, instead of making everything a property just so
that templates work, but by giving up any meaning property could have.

> 
> And who says what good design is?  What if good design means low  
> performance?  What if performance is more important?  How can you say you  
> know the goals of every possible implementable object and whether  
> encapsulation is entirely necessary for it?  You are holding hostage a  
> syntax feature on the concession that it play nice with your "requiring  
> function call" rules.

I believe the principles of OOP are very well established and accepted.
And once again, you don't have to use properties if they don't match
your requirements. Also performance does not suffer from a trivial
get/set functions. (For classes make them final if needed)
> 
> I don't think D should be dictating everything about how you write your  
> properties and methods.  This is a systems language, not a nanny language.
It does not dictate anything. You do accept that you can not do floating
point arithmetic with an integer? What's the difference with properties?
If the tool does not fit your need, don't use it.

> Because then I have to do:
> 
> id.front()();
> 
> To call the delegate.  Not what I wanted to design.  You are calling into  
> question my design because it doesn't suit your DIP.  Why is your DIP more  
> important than my design?

You are questioning my DIP, because it does not match your design. How
is that better? Seriously this is just my point of view, you can agree
or not, all I am trying is to make sure that you understand why I think
it is good and to find possible flaws in it, by discussing it.

It establishes some semantics for properties, instead of simply making
basically everything a property, just so that templates work somehow. 
The DIP increases uniformity among language features, instead of
decreasing it. Also I am obviously convinced that my DIP is a good
solution, otherwise I would not have proposed it.

> > which would still work just the same, if you removed @property.
> 
> Right, the setter is not the reason we need @property on this, it's the  
> getter.  And only for delegate arrays.  I should not have brought this  
> example as a reason for UFCS setter properties.

Not if we simply accept: front()(); as the syntax to go. It might not
look as beautiful as front(), so if you think the syntax for this corner
case is just so utterly ugly that it has to be fixed, well then my
proposal is rubbish.
>  import std.stdio;
> > int i;
> >
> > void main() {
> >     int i;
> >     i=8;
> >     writeln(".i: ", .i);
> >     writeln(".i: ", testglobal.i);
> > }
> >
> > Prints 0 both times. (The file was named testglobal.d)
> 
> I don't know what this example is trying to prove.  I don't see any  
> properties here.
Hmm, maybe I misunderstood your argument against module level
properties. (The example works the same if i was a property) 
So what did you mean by:
	So the point is, a global property could possibly be obscured 
	if you declared a local variable with the same name.

> 
> >> A ref property pretty much behaves EXACTLY like a field.
> >
> > Exactly that is why I don't consider it a property. :-)
> 
> If it's not a property, it does not behave like a field.  If it is a  
> function, then it can behave like a field for all cases except for the  
> delegate case.
right, so its behaviour is uniform with properties.

> Your design dictates that if you want field-like syntax, you have to agree  
> to arbitrary rules regarding ref, and you can't do it with UFCS.  Such  
> rules are pretty much arbitrary, because there is no hidden meaning to a  
> property, they are just functions.  The only benefit is the readability  
> and the 'human' meaning.  Because instead of calling my function setX, I  
> can just call it x, and you have to use the x = ... to call it.

The most important thing the DIP does, is giving "property" an actual
meaning. Also readability is a valid goal, otherwise we could all code
in machine code.

> 
> But you want to assign some guarantees that really aren't guarantees, they  
> are conventions.  In the end, they just get in the way, and your  
> requirements can't achieve the type of guarantees you want.

So you basically say that OOP does not work? (No offense here, but it is
hard to understand for me to understand this statement in any other way)

> 
> Your concept of property is that they are just functions.  But we already  
> HAVE functions.  There is no reason to have a language feature that says  
> "this is a property" unless it dictates the *syntax*.  It is up to the  
> designer of the type to decide how it's parts are called, it should not be  
> up to the caller.  Leaving it up to the caller results in unnecessary  
> obfuscation, and hidden meanings where none was intended.
> 
> There is actually no real need for properties, they are functions, they  
> can be called like functions.  We can get along just fine if we have to  
> write:
> 
> setFoo(x);
> 
> instead of
> 
> foo = x;

Agreed, if we started from scratch and did not want this syntactic
sugar. The problem is we do not start from scratch and we would
basically break every single D program out there.
> 
> If there is any reason to have a @property language feature, it's for  
> syntax, not for design.

At the moment. And I am criticizing this very fact. But if you consider
this a good thing, than I understand your position completely. Because
this way you don't need a meaning of property, you just adopt the rules,
until templates work.
>  ref, don't use @property.
> >
> > So there will be guaranteed to have a proper encapsulated field, the
> > moment they see @property, but what is more important is, that the
> > provider of the code can be sure that he/she got encapsulation right as
> > long as he/she does qualifies something with @property.
> 
> But they don't see property:
> 
> auto x = obj.y; // no @property in sight.

Sure, but how important is this for the caller? The provider of the API
has to ensure compatibility. (Also the caller sees it, if she looked at
the documentation.)
> 
> "guarantees" of encapsulation are easily thwarted:
> 
> struct NotEncapsulated
> {
>     int x;
>     @property int y() { return x;}
> }
> 
Well no language feature in as systems programming language can prevent
you from stupidity. But then, why not get rid of private too, as this is
also possible:

struct {
private int i;
public int* u=&i;
}



More information about the Digitalmars-d mailing list