January 24, 2013
On Thu, 24 Jan 2013 14:15:45 -0800, Robert Schadek <realburner@gmx.de> wrote:

> On 01/24/2013 10:56 PM, Adam Wilson wrote:
>> On Thu, 24 Jan 2013 13:54:09 -0800, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>
>>> On 1/24/13 4:08 PM, Adam Wilson wrote:
>>>> On Thu, 24 Jan 2013 12:58:41 -0800, Andrei Alexandrescu
>>>> <SeeWebsiteForEmail@erdani.org> wrote:
>>>>
>>>>> On 1/24/13 3:45 PM, Nick Sabalausky wrote:
>>>>>> On Thu, 24 Jan 2013 12:51:32 -0500
>>>>>> Andrei Alexandrescu<SeeWebsiteForEmail@erdani.org> wrote:
>>>>>> No, you merely came up with *some* specific cherry-picked examples that
>>>>>> sparked *some* debate (with most of the disagreing coming from
>>>>>> you).
>>>>>
>>>>> I simply mentioned three reasons that came to mind.
>>>>>
>>>>> Andrei
>>>>
>>>> While I don't approve of Mr. Sabalausky's tone or attitude, the crux of
>>>> his argument is logically sound. The problem with @property isn't
>>>> @property, it's D's insistence on optional parens. If paren usage was
>>>> clearly defined then this would be a non-issue. I would like to point
>>>> out that I can't think of another systems/general purpose language that
>>>> has an calling syntax specification as vague and convoluted as D's. C#'s
>>>> is brutally simple. Java's is brutally simple. In C/C++ everything is a
>>>> function or field, so, brutally simple.
>>>>
>>>> Make D's calling syntax simpler, end optional parens!
>>>
>>> Simplicity is clearly good, but there's something to be said about those warts in chained calls. The UFCS-enabled idioms clearly bring a strong argument to the table, there's no ignoring it.
>>>
>>> Andrei
>>
>> Then @property needs to be fixed such that optional parens don't effect it one way or the other. Removing the concept of properties and making functions that look like properties through optional parens is a very poor (and lazy) solution. As Mr. Ruppe pointed out, properties are DATA, and functions do stuff. That statement alone is an excellent argument for clearly delineating which is which... Properties are not functions.
>>
>
> At while you're at it, just get ride of:
>
> int[] a.
> a.length = 10;
>
> That this grows the array stills creeps me out.
>
> Robert

Well, from a syntax standpoint it's legitimate, and D's dynamic arrays are something I prefer over C#'s less flexible solution. My main problem with using it is that D's GC is absurdly naive. When this seemingly benign action causes your program to freeze for non-trivial fractions of a second for the millionth time, it can be quite despair inducing...

-- 
Adam Wilson
IRC: LightBender
Project Coordinator
The Horizon Project
http://www.thehorizonproject.org/
January 24, 2013
On Thursday, 24 January 2013 at 22:27:02 UTC, Robert wrote:
> @property int a;
>
> would be completely equivalent to: <snip>

Not bad.

> Another thing I am wondering, will this still be possible:
>
> void myProperty(int a) @property {}
>
> void function(int) dg=&myProperty;

If I get things my way, no. I'd rewrite that, internally, into &(myProperty()), and then, (unless it returns ref), you'd get an error about can't take address of an rvalue.

There'd be no way, under my preference, to treat a property like a function at all.

> I think it would be quite sensible and useful

Indeed, but there's an easy alternative too that works with both kinds of data, properties and regular: wrapping it in an function at the usage site, e.g. "(a) => myProp = a;"
January 24, 2013
On 01/24/2013 09:13 PM, Andrei Alexandrescu wrote:
> ...
>> Having said that, I'll elaborate on the sentence you quoted above. See
>> for example
>> Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the
>> recursion in the
>> tree-walker.
>
> How about this: insert the parens and then demonstrate how the bug is
> easier to spot. Wasn't any easier for me.
>

There is no bug.
January 24, 2013
On Thu, 24 Jan 2013 14:26:50 -0800, Robert <jfanatiker@gmx.at> wrote:

> Apart from +=, ++, what breaks compatibility of fields and properties,
> is that you can't take the address of a property, but of a field (as
> already mentioned). To increase compatibility and in order to avoid
> breaking peoples' code, when a field is changed to a property, maybe,
> simply offer the possibility to declare fields to be a property too,
> with @property. And make it so that the access to such a field behaves
> exactly the same as to a property: No address taking, and as long as
> properties don't support ++, +=, ... maybe even forbid those.
>
> Example:
>
> @property int a;
>
> would be completely equivalent to:
>
> int a_;
>
> @property int a() {
> return a_;
> }
> @property int a(int new_a) {
>  a_=new_a;
>  return a_;
> }
>
> I think this would suffice to make the property concept really sound and
> working in practice.
>
> If, this is considered a good thing, I could create yet another property
> DIP.
>
> Another thing I am wondering, will this still be possible:
>
> void myProperty(int a) @property {}
>
> void function(int) dg=&myProperty;
>
> Or in other words, will taking the address of a property method still be
> possible? I think it would be quite sensible and useful (for e.g.
> std.signals), taking the address of a transient return value does not
> make any sense anyway, so no ambiguity here. On the other hand it would
> break compatibility with fields again. So if we also want to make sure
> the way back (from property methods to field) works, disallowing taking
> the address might be the way to go for a finally proper implementation.
>
> To the C# experts: How does C# solve those two issues?
>
> Best regards,
>
> Robert
>
>

@Robert, C#'s auto-properties actually do something very close to that. Consider:

property int Count { get; set; }
A read-write integer property with an automatically implemented getter and setter functions in IL.

property int Count { get; }
A read-only integer property with an automatically implemented getter function.

property int Count { set; }
A write-only integer property with an automatically implemented setter function. This is rarely used, but I have seen it.

C# then creates an unseen field _CountBacking that is only the IL, not in the user code. The getter/setter then work against this field.

This capability was first introduced in C# 3.0 in 2005. The majority of properties are implemented this way in C# care nowadays.

The one problem with your example is that you haven't defined a way to make the property read-only/write-only like in C#.

-- 
Adam Wilson
IRC: LightBender
Project Coordinator
The Horizon Project
http://www.thehorizonproject.org/
January 24, 2013
On 1/24/2013 12:58 PM, mist wrote:
> <rage>Please. Go to http://wiki.dlang.org/Release_Process . Read it. Answer the
> question "Hm, does having well-defined release process with long-term support
> versions help with instability of breaking changes?". And if answer is "no" then
> you probably should have contributed your opinion there for a long time, because
> it _should_ to.</rage>
>
> Really, all this backwards-compatibility talk is a crap. There is no way we can
> say current D design is final and solid and can be polished without any breaking
> changes. We should not argue about how bad breaking is. We should discus how to
> do those changes in the least harmful way.

Having a release process does not remove the pain of breaking changes that make users miserable because their older code no longer compiles.
January 24, 2013
Proper property design:
> 
> @property int a;
> 
gets actually lowered by the compiler to:
> 
> int a_;
> 
> @property int a() {
> return a_;
> }
> @property int a(int new_a) {
>  a_=new_a;
>  return a_;
> }
> 
-> field property, and get/set property are actually the same thing. -> It is guaranteed that they behave the same way and can always be exchanged.

-> Taking the address of the getter/setter also always works, enabling things like connecting the setter to a signal for example.

I don't know about you guys, but I love this. It is just perfect. What do I miss?

Best regards,

Robert

January 24, 2013
On Thu, 24 Jan 2013 14:47:44 -0800, Robert <jfanatiker@gmx.at> wrote:

> Proper property design:
>>
>> @property int a;
>>
> gets actually lowered by the compiler to:
>>
>> int a_;
>>
>> @property int a() {
>> return a_;
>> }
>> @property int a(int new_a) {
>>  a_=new_a;
>>  return a_;
>> }
>>
> -> field property, and get/set property are actually the same thing. ->
> It is guaranteed that they behave the same way and can always be
> exchanged.
>
> -> Taking the address of the getter/setter also always works, enabling
> things like connecting the setter to a signal for example.
>
> I don't know about you guys, but I love this. It is just perfect. What
> do I miss?
>
> Best regards,
>
> Robert
>


The syntax provides no way to define read-only or write-only properties. Other than that I love it, but I am a biased C# guy.

-- 
Adam Wilson
IRC: LightBender
Project Coordinator
The Horizon Project
http://www.thehorizonproject.org/
January 24, 2013
On 01/24/2013 08:03 PM, Artur Skawina wrote:
> ...
>
> Having said that, I'll elaborate on the sentence you quoted above. See for example
> Timon's code [1] here: http://dpaste.dzfl.pl/baa538af . Spot the recursion in the
> tree-walker. This is an example of the kind of abuse of parens-less calls that an
> unsuspecting programmer shouldn't have to deal with. Sure, in this case it's simple
> enough, but in more complex scenarios, where the 'inorder' field/method/ufcs
> definition is not readily available, it would be extremely misleading. It's not
> reasonable to expect everyone reading the code to check every single object field
> access, just in case the previous coder decided that the source looked "cuter"
> w/o the '()'.
> ...

Uh...

class Tree(T){
    InOrder!T inorder;
    this(){inorder = InOrder!T(this); }
    Tree!T l,r;
    T v;
}
auto tree(T)(Tree!T l, T v, Tree!T r){
    auto t = new Tree!T;
    t.l=l;t.r=r;t.v=v;
    return t;
}
auto tree(T)(T v){ return tree(Tree!T.init,v,Tree!T.init); }
struct InOrder(T){
    this(Tree!T c){container=c;}
    Tree!T container;
    InOrder* t;
    mixin Yield!(q{
        if (container.l !is null){
            for(t=[container.l.inorder].ptr;!t.empty;t.popFront())
                yield t.front;
        }
        yield container.v;
        if (container.r !is null){
            for(t=[container.r.inorder].ptr;!t.empty;t.popFront())
                yield t.front;
        }
    },T);
}
//InOrder!T inorder(T)(Tree!T container){ return InOrder!T(container); }

January 24, 2013
Yeah, I thought of that and the compiler can optimize it away if not needed. So this would be fine, but see my second, improved proposal.

On Thu, 2013-01-24 at 23:37 +0100, Adam D. Ruppe wrote:
> Indeed, but there's an easy alternative too that works with both kinds of data, properties and regular: wrapping it in an function at the usage site, e.g. "(a) => myProp = a;"




January 24, 2013
There is, just don't do:

@property int a;

but

int a_;

@property int a() { return a_}

-> Omitting the setter. It is a bit more verbose than the C# version, but adding syntactic sugar later on, if really desired, should not be too hard.

And thanks for the C# implementation description.


On Thu, 2013-01-24 at 14:48 -0800, Adam Wilson wrote:
> The syntax provides no way to define read-only or write-only
> properties.
> Other than that I love it, but I am a biased C# guy.