February 09, 2013
On 2013-02-09 12:32, Robert wrote:
> Has anyone actually read the DIP?
>
> Simply don't call it property.

Fine for getters but this time it will break things for setters:

    @property void front(T)(T[] arr, T elem) {...}

and either all code with assignments would have to be changed
or assignments remain allowed for functions -- neither is good.

February 09, 2013
As you can't actually encapsulate the array with free functions just do:

ref T front(T)(T[] arr);

There is no value in using an actual setter.

If you really want encapsulation, just do:

struct EncapsulatedArray(T) {
T front() @property;
void front(T value) @property;
private T[] arr_;
}

On Sat, 2013-02-09 at 12:43 +0100, FG wrote:
> On 2013-02-09 12:32, Robert wrote:
> > Has anyone actually read the DIP?
> >
> > Simply don't call it property.
> 
> Fine for getters but this time it will break things for setters:
> 
>      @property void front(T)(T[] arr, T elem) {...}
> 
> and either all code with assignments would have to be changed or assignments remain allowed for functions -- neither is good.
> 


February 09, 2013
On 2013-02-09 12:57, Robert wrote:
> As you can't actually encapsulate the array with free functions just do:
>
> ref T front(T)(T[] arr);
>
> There is no value in using an actual setter.

Ah, sorry, you're right. It's an lvalue, so no setter is needed.

February 09, 2013
On 2013-02-09 11:58:23 +0000, Jonathan M Davis <jmdavisProg@gmx.com> said:

> You must be able to rely on front always being used without parens, and you
> must be able to rely on front() doing a call on the return value rather than
> simply calling front. Otherwise, you're going to have problems with code
> erroneously using parens to call front and breaking when used with anything
> that actually defines it as a property, and you'll break anything involving
> delegates or other callables. Returning ref is irrelevant, especially if we
> get full property rewrites (e.g. front += 7 and the like works with property
> functions without ref). What matters is that the syntax is consistent and that
> the semantics of using parens on front are consistent. Generic code needs to
> work with anything with the right API, and making front a function will cause
> problems with that.

I'll agree with you that it'd be better if properties were allowed with UFCS too. At the same time, this DIP removes much of the boilerplate of writing properties, so it's not only a "fix" for the current problems, it's also a much welcome improvement over what we have. It doesn't address the UFCS issue, but that doesn't prevent it from being fixed in other ways.

For instance we could add a 'this' argument (not that I favour this particular syntax):

	@property void front(int[] this, int value);

One problem we currently have is that the way properties are defined with @property is that there's no way to distinguish module-level properties from UFCS properties. Instead of fixing that, many people are trying to disallow one or the other. So instead of fixing the real problem, people have divided into two camps: one that likes module-level properties and one that likes UFCS ones. Both sides wanting to disallow the other's side pet feature. I find the situation somewhat ridiculous. Whatever side we choose, it'll break the language coherency while alienating many people.

I believe both module-level properties and UFCS properties to be desirable. So is the idea put forward in DIP26 that reduces boilerplate code. The question is how do we put all that together.

-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca/

February 09, 2013
I am going to consider these. Thanks!
On Fri, 2013-02-08 at 22:13 -0500, Michel Fortin wrote:
> On 2013-02-08 23:53:30 +0000, Robert <jfanatiker@gmx.at> said:
> 
> > Ok. Here finally it is:
> > 
> > http://wiki.dlang.org/DIP26
> 
> This is pretty much exactly how I think properties should work. There's two possible benefits you may to have overlooked…
> 
> One benefit of the "@property T foo;" syntax that does the boilerplate code for you over using a plain variable: the getter and setter generated are virtual in a class, so a derived class can override them. Doesn't work with a plain variable.
> 
> Another possible benefit that we could have is the ability to use the default getter but to provide your own setter implementation by just declaring it:
> 
> 	@property int a;
> 	@property void a(int value) { __a = value; refresh(); }
> 
> Much cleaner than this:
> 
> 	private int _a;
> 	@property int a() { return _a; }
> 	@property void a(int value) { _a = value; refresh(); }
> 
> It's really great to not have to write boilerplate functions when default behaviour is perfectly fine. I've been using Objective-C for a while now and the recent changes where it automatically synthesize a variable, a getter, and a setter when declaring a property (unless you provide your own) are truly delightful.
> 


February 09, 2013
On Sat, 2013-02-09 at 08:28 +0100, deadalnix wrote:
> Taking the address of a property  <= no. It I take the address of
> an int, I get an int* or an error because it is invalid. Not a
> delegate !
> No UFCS for properties <= no.
> Behaviour like functions <= WTF should properties behave
> differently if the return a function ?

You are still thinking of properties as fields. Which does not work reliable in any proposal and actually can not, that is the reason for encapsulation in the first place.

My arguments against UFCS for properties make a lot of sense if you think about it and result in a very clean implementation, with little breakage and the added benefit of actually having something that deserves to be called property.

The other proposals try to solve the issue of functions returning functions being inconsistent across real functions and some property like thing that tries (badly) to mimic a field, by making property just more non sensical, instead of tackling the root cause of the problem:

We can not mimic fields and in fact there is absolutely no reason to do so, if you think about it, you don't really want that, otherwise all books about OOP would be wrong.

February 09, 2013
I wrote:

> I believe both module-level properties and UFCS properties to be desirable. So is the idea put forward in DIP26 that reduces boilerplate code. The question is how do we put all that together.

Andrei just made me realize that I overlooked this part of DIP26 which actually solve the most of the problem of UFCS (see the Upgrade Path section):

> Generic code won't break: It can use optional parentheses, but does not have to. Calling a delegate returned by a function/property function is always:
> front()();

So whether a getter is a property or not does not change anything at the call site, meaning that UFCS getters (or any getter with no associated setter for that matter) don't need to be properties. What remains is that you can't write UFCS *setters*. But UFCS setters are definitely less common, and if that's really important I guess it could be solved though separate means.

So in short, this proposal is that @property does only two things when applied to a function: it enables the setter syntax and it changes the overload rules.

I like the conclusion:

> So this DIP is exactly the opposite approach of solving the property problem: Don't make them look more like fields, make public fields more look like functions.
> 
> Don't try to make functions look like fields, this can not work. Just do it the other way round: Don't ever make a field public, but use properties, as every OOP book tells you anyway. And all problems are solved, as far as I can see.

-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca/

February 09, 2013
On 2013-02-09 10:57, Tove wrote:

> @property int a;
>
> I would prefer if @property simply disallows '&' then it doesn't have to
> be lowered into anything and can stay a field... if you later decide to
> add a "real" getter/setter, it still would be source compatible and you
> wouldn't have to refactor the source.

If it's not lowered to functions they won't be virtual, which might be wanted.

-- 
/Jacob Carlborg
February 09, 2013
On 2013-02-09 04:13, Michel Fortin wrote:

> This is pretty much exactly how I think properties should work. There's
> two possible benefits you may to have overlooked…
>
> One benefit of the "@property T foo;" syntax that does the boilerplate
> code for you over using a plain variable: the getter and setter
> generated are virtual in a class, so a derived class can override them.
> Doesn't work with a plain variable.
>
> Another possible benefit that we could have is the ability to use the
> default getter but to provide your own setter implementation by just
> declaring it:
>
>      @property int a;
>      @property void a(int value) { __a = value; refresh(); }
>
> Much cleaner than this:
>
>      private int _a;
>      @property int a() { return _a; }
>      @property void a(int value) { _a = value; refresh(); }
>
> It's really great to not have to write boilerplate functions when
> default behaviour is perfectly fine. I've been using Objective-C for a
> while now and the recent changes where it automatically synthesize a
> variable, a getter, and a setter when declaring a property (unless you
> provide your own) are truly delightful.

I completely agree, I really like it. Do we want to be able to use attributes like "final", and perhaps others, when declaring a property field:

@property final int a;

The lowered functions would have the "final" attribute attached to them self.

-- 
/Jacob Carlborg
February 09, 2013
On Saturday, 9 February 2013 at 12:44:35 UTC, Michel Fortin wrote:
> One problem we currently have is that the way properties are defined with @property is that there's no way to distinguish module-level properties from UFCS properties. Instead of fixing that, many people are trying to disallow one or the other. So instead of fixing the real problem, people have divided into two camps: one that likes module-level properties and one that likes UFCS ones. Both sides wanting to disallow the other's side pet feature. I find the situation somewhat ridiculous. Whatever side we choose, it'll break the language coherency while alienating many people.
>
> I believe both module-level properties and UFCS properties to be desirable. So is the idea put forward in DIP26 that reduces boilerplate code. The question is how do we put all that together.

Well design is a balance between conflicting goals. Allowing both cause an extra complication. So the win have to actually be carefully considered.

@properties as UFCS are almost mandatory. They are used everywhere, especially for arrays. I don't really know what is the state of thing in module level @property, but I never used them or required them. Can you give use cases of desirables module level properties ?