May 07, 2012
On Mon, 07 May 2012 15:35:35 -0400, Jacob Carlborg <doob@me.com> wrote:

> On 2012-05-07 14:43, Steven Schveighoffer wrote:
>
>> It's like this in C#.
>>
>> I can't decide whether I like it better in D or C#. Clearly the compiler
>> lowering of foo |= 2 to foo = foo | 2 would be benficial in terms of
>> less code to write.
>>
>> But I also like having control over how properties can implement
>> operators. For example, the above is two function calls, but it may be
>> easier/more efficient written as one. The issue is, how do you do that?
>>
>> The current definition syntax doesn't lend itself well to extension...
>>
>> -Steve
>
> If an operator is overloaded use that single function, otherwise do a rewirte.

How do you overload the operator for a property?  For example:

struct S
{
   int x;
}

struct T
{
   private int _x;
   @property S s() { return S(_x);}
   @property void s(S news) { _x = newS.x; }
}

How do I define T.s |= 5 ???

I realize we could define opBinary("|") on S, and depend on the rewrite, but I'd rather do it in one operation.

-Steve
May 07, 2012
On Monday, 7 May 2012 at 12:43:42 UTC, Steven Schveighoffer wrote:
> On Sun, 06 May 2012 22:05:20 -0400, Mehrdad <wfunction@hotmail.com> wrote:
>
>> Why doesn't this compile?
>>
>> @property int foo() { return 1; }
>> @property void foo(int v) { }
>>
>> void main()
>> {
>> 	foo |= 2;
>> }
>
> It's like this in C#.

Um, I to differ...
This compiles just fine in C#:

class Program
{
	static int Prop { get { return 0; } set { } }
	static void Main()
	{
		Prop |= 1;
	}
}
May 07, 2012
On Monday, 7 May 2012 at 02:05:21 UTC, Mehrdad wrote:
> Why doesn't this compile?
>
> @property int foo() { return 1; }
> @property void foo(int v) { }
>
> void main()
> {
> 	foo |= 2;
> }


import std.stdio;

int pro = 1;

@property ref auto prop()
{
      return pro;
}

@property void prop(int value)
{
      pro = value;
}

void main()
{
      writeln(prop |= 2);
}

No?

// dmd 2.059

May 07, 2012
On Monday, 7 May 2012 at 20:16:27 UTC, Michael wrote:
> No?

No.

Remove "@property void prop(int value)" and see what happens.
May 07, 2012
Definitely a lot more code, but maybe something like this would
work for this problem:
https://gist.github.com/c65e2cc6011d7887efcd
May 07, 2012
On Mon, 07 May 2012 16:15:54 -0400, Mehrdad <wfunction@hotmail.com> wrote:

> On Monday, 7 May 2012 at 12:43:42 UTC, Steven Schveighoffer wrote:
>> On Sun, 06 May 2012 22:05:20 -0400, Mehrdad <wfunction@hotmail.com> wrote:
>>
>>> Why doesn't this compile?
>>>
>>> @property int foo() { return 1; }
>>> @property void foo(int v) { }
>>>
>>> void main()
>>> {
>>> 	foo |= 2;
>>> }
>>
>> It's like this in C#.
>
> Um, I to differ...

Oh! I didn't express myself properly :)  It's like this in C# means that the above *does* compile in C# :)  Sorry for the confusion.

-Steve
May 07, 2012
On 2012-05-07 21:53, Steven Schveighoffer wrote:

> How do you overload the operator for a property? For example:

Hm, I didn't think that one through :)

-- 
/Jacob Carlborg
May 07, 2012
On 2012-05-07 22:16, Michael wrote:
> import std.stdio;
>
> int pro = 1;
>
> @property ref auto prop()
> {
>        return pro;
> }
>
> @property void prop(int value)
> {
>        pro = value;
> }
>
> void main()
> {
>        writeln(prop |= 2);
> }

You're bypassing the getter.

-- 
/Jacob Carlborg
May 07, 2012
On Monday, May 07, 2012 23:14:36 Jacob Carlborg wrote:
> On 2012-05-07 22:16, Michael wrote:
> > import std.stdio;
> > 
> > int pro = 1;
> > 
> > @property ref auto prop()
> > {
> > 
> >        return pro;
> > 
> > }
> > 
> > @property void prop(int value)
> > {
> > 
> >        pro = value;
> > 
> > }
> > 
> > void main()
> > {
> > 
> >        writeln(prop |= 2);
> > 
> > }
> 
> You're bypassing the getter.

You mean the setter?

Having a getter property function return by ref does allow you to use a property exactly as you would a variable, because you're operating on the ref that's returned. It also makes the property function nigh-on-useless, because then you're operating on its associated variable outside of the property function, making it so that you can no longer control access to it. You pretty much might as well make it a public variable at that point. Not to mention, even if returning by ref didn't have that problem, it would only work in cases where the property function was associated with an actual variable (since you have to return a ref to _something_), so it would still be impossible to emulate a variable with property functions which calculate the value from other variables or which grab the value from somewhere else (e.g. a database).

- Jonathan M Davis
May 07, 2012
On Monday, 7 May 2012 at 21:34:29 UTC, Jonathan M Davis wrote:
> You mean the setter?
>
> Having a getter property function return by ref does allow you to use a
> property exactly as you would a variable, because you're operating on the ref
> that's returned. It also makes the property function nigh-on-useless, because
> then you're operating on its associated variable outside of the property
> function, making it so that you can no longer control access to it. You pretty
> much might as well make it a public variable at that point. Not to mention,
> even if returning by ref didn't have that problem, it would only work in cases
> where the property function was associated with an actual variable (since you
> have to return a ref to _something_), so it would still be impossible to
> emulate a variable with property functions which calculate the value from
> other variables or which grab the value from somewhere else (e.g. a database).
>
> - Jonathan M Davis

And what about my idea of returning a struct by ref and using a struct to represent all of the operations you're interested in? As far as I can see, it should work, but admittedly, it's not as slick as it could be.