February 02, 2013
On Saturday, 2 February 2013 at 21:21:28 UTC, Rob T wrote:
> On Saturday, 2 February 2013 at 15:56:41 UTC, TommiT wrote:
> [..]
>>
>> Memberspaces shouldn't feel like variables at all. They should feel exactly like C++ namespaces that live inside a struct or a class. [..]
>
> Rather than feel exactly like C++ namespaces, [..]

Just to be clear, I didn't say/mean that memberspaces should feel exactly like C++ namespaces, nor is there any change that they would, given that in C++ namespaces can't live inside structs or classes and they use :: to separate them. Forgive me for explaining all that, in case you know C++ (I can't assume that everybody does).
February 02, 2013
On Saturday, 2 February 2013 at 21:39:45 UTC, TommiT wrote:
> I think we can use template mixins to achieve that:
>
> mixin template add_stuff(alias var)
> {
>     memberspace stuff
>     {
>         typeof(var) opCall() const
>         {
>             return var;
>         }
>
>         void opAssign(typeof(var) rhs)
>         {
>             var = rhs;
>         }
>     }
> }
>
> struct S
> {
>     int _value;
>
>     mixin add_stuff!(_value);
> }
>
> void main()
> {
>     S s;
>     s.stuff = 42;
>     assert(s.stuff() == 42);
> }

And here's how you could even add the name of your memberspace as one of the template mixin parameters:

mixin template basic_property(alias prop, alias var)
{
    memberspace prop
    {
        typeof(var) opCall() const
        {
            return var;
        }

        void opAssign(typeof(var) rhs)
        {
            var = rhs;
        }
    }
}

struct S
{
    int _value;

    memberspace myprop { }

    mixin basic_property!(myprop, _value);
}

void main()
{
    S s;
    s.myprop = 42;
    assert(s.myprop() == 42);
}
February 02, 2013
On Saturday, February 02, 2013 10:14:29 TommiT wrote:
> I propose we just forget about the whole concept of a property

I think that this proves that the property discussion has gotten way out of hand. The real question is whether we think that we need explicit properties or not. If we don't, then presumably, we'll end up with some variant of what Walter has suggestiing. If we do, then I see no reason to do anything other than just fixing up the implementation of @property. The problems with it are almost entirely due to a lack of being properly implemented rather than there being a problem with its design. Really, the only major design issue with @property that's been being debated is whether it should make it so that parens are required on normal function calls, and everything else about @property is actually indepedent of that.

I don't think that we should be trying to add major, new concepts right now. I think that we should just decide whether or not we need explicit properties. And that will decide whether we go with a variant of what Walter is suggesting or whether we do something with @property. All these other suggestions are just complicating things to no real benefit.

- Jonathan M Davis
February 02, 2013
On Saturday, 2 February 2013 at 22:18:52 UTC, Jonathan M Davis wrote:
> On Saturday, February 02, 2013 10:14:29 TommiT wrote:
>> I propose we just forget about the whole concept of a property
>
> I think that this proves that the property discussion has gotten way out of hand.

I don't see that quoted sentence of mine as a proof that the discussion has gotten out of hand. It only shows that I personally think that memberspaces are semantically such a close match to the concept of properties, that I don't see any reason to think of them as different things.

BTW, given that we fix the @property attribute, would the line:
s.prop += 3;
...call:
1) s.prop( s.prop + 3 );
...or:
2) s.prop().opOpAssign!"+"(3);
...in the code snippet below:

struct T
{
    private int _value;

    ref T opAssign(int rhs)
    {
        _value = rhs;
        return this;
    }

    ref T opOpAssign(string op)(int rhs)
        if(op == "+" || op == "-")
    {
        mixin("_value" ~ op ~ "= rhs;");
        return this;
    }

    T opBinary(string op)(int rhs) const
        if(op == "+" || op == "-")
    {
        T t = this;
        mixin("t._value" ~ op ~ "= rhs;");
        return t;
    }
}

struct S
{
    private T _t;

    @property ref T prop()
    {
        return _t;
    }

    @property void prop(int v)
    {
        _t = v;
    }
}

void main()
{
    S s;
    s.prop += 3; // ?
}
February 02, 2013
On Saturday, 2 February 2013 at 22:18:52 UTC, Jonathan M Davis wrote:
> [..] All these other suggestions are
> just complicating things to no real benefit.

You say "there's no real benefit". I say "there's the benefit of being able to add another layer of encapsulation when it's needed". Here's what I mean by that:

The lack of encapsulation with @property attribute:

struct T
{
    private int _value;

    void add_twice(int v)
    {
        _value += 2 * v;
    }
}

struct S
{
    private T _t;
    private int _sum_of_squares; // Can't update this

    @property ref T prop()
    {
        return _t;
    }
}

void main()
{
    S s;
    s.prop.add_twice(); // *Not* incrementing s._sum_of_squares
}

...Whereas with memberspaces we can add that extra layer of encapsulation:

struct S
{
    private T _t;
    private int _sum_of_squares;

    memberspace prop
    {
        ref const(T) opCall() const
        {
            return _t;
        }

        void add_twice(int v)
        {
            _sum_of_squares += (2 * v)^2; // Yippee!
            return _t.add_twice(v);
        }
    }
}
February 03, 2013
On Saturday, 2 February 2013 at 22:18:52 UTC, Jonathan M Davis wrote:
>
> I don't think that we should be trying to add major, new concepts right now. I
> think that we should just decide whether or not we need explicit properties.
> And that will decide whether we go with a variant of what Walter is suggesting
> or whether we do something with @property. All these other suggestions are
> just complicating things to no real benefit.
>
> - Jonathan M Davis

@property is a dead end IMHO because it adds little to the language and can never be used to emulate real variables. The memberspace concept does at least as well as @property can ever do and is a more generalized solution that can be used beyond just implementing properties. Why bother with @property when we can much better?

--rt
February 03, 2013
On Saturday, 2 February 2013 at 23:23:37 UTC, TommiT wrote:
> You say "there's no real benefit". I say "there's the benefit of being able to add another layer of encapsulation when it's needed". Here's what I mean by that:
>
> The lack of encapsulation with @property attribute:
>
> struct T
> {
>     private int _value;
>
>     void add_twice(int v)
>     {
>         _value += 2 * v;
>     }
> }
>
> struct S
> {
>     private T _t;
>     private int _sum_of_squares; // Can't update this
>
>     @property ref T prop()
>     {
>         return _t;
>     }
> }
>
> void main()
> {
>     S s;
>     s.prop.add_twice(); // *Not* incrementing s._sum_of_squares
> }

 I'd just call that bad design, I wouldn't reference a variable like that  unless it's returned const or I don't care about if anything else accesses it. Since T/_t is private you shouldn't be giving access to them without a good reason.


> ...Whereas with memberspaces we can add that extra layer of encapsulation:
>
> struct S
> {
>     private T _t;
>     private int _sum_of_squares;
>
>     memberspace prop
>     {
>         ref const(T) opCall() const
>         {
>             return _t;
>         }

 So this one's allowed a const get return....

>         void add_twice(int v)
>         {
>             _sum_of_squares += (2 * v)^2; // Yippee!
>             return _t.add_twice(v);
>         }
>     }
> }

 Hmmm curiously the above previous example didn't include add_twice outside of T. had it of and had a const get I'm sure these would be about the same.

 I'll your example(s) here reflect a bad/different design rather than why namespaces should be used.

 Besides, wasn't namespaces in D handled due to initial modular setup and alias?
February 03, 2013
On Sunday, 3 February 2013 at 01:45:14 UTC, Era Scarecrow wrote:
> On Saturday, 2 February 2013 at 23:23:37 UTC, TommiT wrote:
>> You say "there's no real benefit". I say "there's the benefit of being able to add another layer of encapsulation when it's needed". Here's what I mean by that:
>>
>> The lack of encapsulation with @property attribute:
>>
>> struct T
>> {
>>    private int _value;
>>
>>    void add_twice(int v)
>>    {
>>        _value += 2 * v;
>>    }
>> }
>>
>> struct S
>> {
>>    private T _t;
>>    private int _sum_of_squares; // Can't update this
>>
>>    @property ref T prop()
>>    {
>>        return _t;
>>    }
>> }
>>
>> void main()
>> {
>>    S s;
>>    s.prop.add_twice(); // *Not* incrementing s._sum_of_squares
>> }
>
>  I'd just call that bad design, I wouldn't reference a variable like that  unless it's returned const or I don't care about if anything else accesses it. Since T/_t is private you shouldn't be giving access to them without a good reason.
>
>
>> ...Whereas with memberspaces we can add that extra layer of encapsulation:
>>
>> struct S
>> {
>>    private T _t;
>>    private int _sum_of_squares;
>>
>>    memberspace prop
>>    {
>>        ref const(T) opCall() const
>>        {
>>            return _t;
>>        }
>
>  So this one's allowed a const get return....
>
>>        void add_twice(int v)
>>        {
>>            _sum_of_squares += (2 * v)^2; // Yippee!
>>            return _t.add_twice(v);
>>        }
>>    }
>> }
>
>  Hmmm curiously the above previous example didn't include add_twice outside of T. had it of and had a const get I'm sure these would be about the same.
>
>  I'll your example(s) here reflect a bad/different design rather than why namespaces should be used.

I agree that the example of mine which used @property attribute is a bad design, and that's exactly my point. The point is that it's impossible to create a good design of 'S' with @property attribute, if the interface is required to have a property-like syntax. And if the interface isn't required to provide a property-like syntax, then what are we even talking about?

In order to implement the same level of encapsulation as there is in the example of mine which uses memberspaces, you'd probably prefix the method names with the name of the property to make a hint to the user that those things are linked to each other. That indicates a failure in what @property attribute tries to accomplish. Anyway, it would look something like this:

struct S
{
    private T _t;
    private int _sum_of_squares;

    @property ref const(T) prop() const
    {
        return _t;
    }

    // This method here shows that our attempts at creating
    // property semantics with @property attribute has failed:
    void prop_add_twice(int v)
    {
        _sum_of_squares += (2 * v)^^2;
        _t.add_twice(v);
    }
}


On Sunday, 3 February 2013 at 01:45:14 UTC, Era Scarecrow wrote:
>  Besides, wasn't namespaces in D handled due to initial modular setup and alias?

Module-level and type-level are two different things.
1 2
Next ›   Last »