www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Static operator overloads are possible why?

reply Giles Bathgate <gilesbathgate gmail.com> writes:
Dear Mr Bright;

I have been playing with D and have come across what I believe to be a
bug/feature idea.

It all started when I tried to emulate C# Style events, (Dont worry this is not
a request to add events to the language) 
I was really impressed by the power of the D language and found that I could
make what microsoft call Multicast delegates
So in my opinion there is no need to add them.

However,

the way I add handlers to the multicast delegate is using the following syntax:

this.add_Paint = new PaintEventHandler(&Form1_Paint);

as opposed to microsofts syntax of

this.Paint += new PaintEventHandler(Form1_Paint);

So I started investigating using opAddAssign overloads.

Ok Introduction over Let me get to the point.

Consider the following code:


public class Test
{
	public char[] Name;

	public Test opAddAssign(Test value)
	{
		writefln(value.Name);
		//TODO...
	}
} 

int Main()
{
	Test t;
	Test b = new Test();

	t += b; //Runtime exception because t is null

}

This code obviously has a runtime exception because t was not assigned and the
translation of the code t += b; becomes 
t.opAddAssign(b); 'ok I thought', I shall make the operator overload
static...'er no wait can I do that?'

half expecting a compile error I tried anyway


public class Test
{
	public char[] Name;

	public static Test opAddAssign(Test value)
	{
		writefln(value.Name);
		//TODO...
	}
} 

int Main()
{
	Test t;
	Test b = new Test();
	b.Name = "foo"

	t += b; // Translates to:   Test.opAddAssign(b);

}

output: foo

The code compiles, and runs, and opAddAssign actually gets called, 

but wait surely t += b; translates to Test.opAddAssign(b);    

So how is that in anyway usefull? we have no reference to t, within our
operator overload call. 
(In the first example the reference to t could have been referenced by this)

So my question; 'should static operator overloads even be allowed?'
and if they were to be allowed should they not have two arguments?

thus:

static Test opAddAssign(Test t, Test value){...}


then 

t += b;

becomes

Test.opAddAssign(t,b);

Static operator overloads would be useful to me for this one particular
application.
Whats you view?

Regards

Mr _Bathgate;
Jun 29 2007
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Just a couple of quick comments about your post:
1) It looks like you're reinventing std.signals.
2) The usual operator for adding another handler onto a list is ~= 
(opCatAssign) not +=.

--bb



Giles Bathgate wrote:
 Dear Mr Bright;
 
 I have been playing with D and have come across what I believe to be a
bug/feature idea.
 
 It all started when I tried to emulate C# Style events, (Dont worry this is
not a request to add events to the language) 
 I was really impressed by the power of the D language and found that I could
make what microsoft call Multicast delegates
 So in my opinion there is no need to add them.
 
 However,
 
 the way I add handlers to the multicast delegate is using the following syntax:
 
 this.add_Paint = new PaintEventHandler(&Form1_Paint);
 
 as opposed to microsofts syntax of
 
 this.Paint += new PaintEventHandler(Form1_Paint);
 
 So I started investigating using opAddAssign overloads.
 
 Ok Introduction over Let me get to the point.
 
 Consider the following code:
 
 
 public class Test
 {
 	public char[] Name;
 
 	public Test opAddAssign(Test value)
 	{
 		writefln(value.Name);
 		//TODO...
 	}
 } 
 
 int Main()
 {
 	Test t;
 	Test b = new Test();
 
 	t += b; //Runtime exception because t is null
 
 }
 
 This code obviously has a runtime exception because t was not assigned and the
translation of the code t += b; becomes 
 t.opAddAssign(b); 'ok I thought', I shall make the operator overload
static...'er no wait can I do that?'
 
 half expecting a compile error I tried anyway
 
 
 public class Test
 {
 	public char[] Name;
 
 	public static Test opAddAssign(Test value)
 	{
 		writefln(value.Name);
 		//TODO...
 	}
 } 
 
 int Main()
 {
 	Test t;
 	Test b = new Test();
 	b.Name = "foo"
 
 	t += b; // Translates to:   Test.opAddAssign(b);
 
 }
 
 output: foo
 
 The code compiles, and runs, and opAddAssign actually gets called, 
 
 but wait surely t += b; translates to Test.opAddAssign(b);    
 
 So how is that in anyway usefull? we have no reference to t, within our
operator overload call. 
 (In the first example the reference to t could have been referenced by this)
 
 So my question; 'should static operator overloads even be allowed?'
 and if they were to be allowed should they not have two arguments?
 
 thus:
 
 static Test opAddAssign(Test t, Test value){...}
 
 
 then 
 
 t += b;
 
 becomes
 
 Test.opAddAssign(t,b);
 
 Static operator overloads would be useful to me for this one particular
application.
 Whats you view?
 
 Regards
 
 Mr _Bathgate;

Jun 29 2007
parent reply Giles Bathgate <gilesbathgate gmail.com> writes:
Bill Baxter Wrote:

 Just a couple of quick comments about your post:
 1) It looks like you're reinventing std.signals.

Its irrelavent how i got to the example scenario, but thanks for the tip I wasn't aware of std.signals.
 2) The usual operator for adding another handler onto a list is ~= 
 (opCatAssign) not +=.

Ok fair point. but the same issue exists consider the following code: public class Test { public char[] Name; public static Test opCatAssign(Test value) { writefln(value.Name); writefln("Where is t?"); } } int main() { Test t; Test b = new Test(); b.Name = "foo"; t ~= b; } t ~= b; Translates to This.opCatAssign(b); Where does t go?
Jun 30 2007
parent Giles Bathgate <gilesbathgate gmail.com> writes:
...That should have been

t ~= b;      Translates to Test.opCatAssign(b);

Where does t go.

Surely if opCatAssign is static then

t ~= b;     Translates to Test.opCatAssign(t,b);
Jun 30 2007
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
Giles Bathgate wrote:
 
 So how is that in anyway usefull? we have no reference to t, within our
operator overload call. 
 (In the first example the reference to t could have been referenced by this)
 
 So my question; 'should static operator overloads even be allowed?'
 and if they were to be allowed should they not have two arguments?

Personally, I find the existing static operator overloads to be a useful tool for various (rarely used, I admit) syntactic tricks. Aside from static opCall being the only means of providing a struct ctor at the moment, such things also allow certain types of code to be refactored in a fairly efficient manner. Consider expression templates, for example. Being able to operate directly on types can help to reduce the need for placeholder structs in some cases. Sean
Jun 29 2007
parent reply Giles Bathgate <gilesbathgate gmail.com> writes:
Thanks sean you have answered the question in the subject line, I posed the
question that way to prevoke a response. I agree that static operator overloads
should be possible, my post is really directed at the issue of how one would
use them.

e.g in my example for static operator overloads if t += b; translates to
Test.opAddAssign(b); then where does the reference to t go? surely it should be
Test.opAddAssign(t,b);
Jun 30 2007
parent Sean Kelly <sean f4.ca> writes:
Giles Bathgate wrote:
 Thanks sean you have answered the question in the subject line, I posed the
question that way to prevoke a response. I agree that static operator overloads
should be possible, my post is really directed at the issue of how one would
use them.
 
 e.g in my example for static operator overloads if t += b; translates to
Test.opAddAssign(b); then where does the reference to t go? surely it should be
Test.opAddAssign(t,b);

There is no reference to t in that case -- it's a static operation. ie. you can do things like this: struct S { static int opMul( int x ) { return x * 5; } } int y = S * 2; // should equal 10 This becomes useful mostly when you have multiple operator overloads for different types, and do different things for each type. Sean
Jun 30 2007
prev sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Giles Bathgate" <gilesbathgate gmail.com> wrote in message 
news:f63vfc$29vg$1 digitalmars.com...

 public class Test
 {
 public char[] Name;

 public Test opAddAssign(Test value)
 {
 writefln(value.Name);
 //TODO...
 }
 }

 int Main()
 {
 Test t;
 Test b = new Test();

 t += b; //Runtime exception because t is null

 }

You can access static class members through variables which are of that class's type. This applies to all static methods and fields; static operator overloads are no exception. I'm not entirely sure why you can do this; it's probably "the way C++ does it." That being said, I'm not sure why you decided to try a static overload instead of just new'ing t. Another solution would be to make your multicast delegate a struct type instead, which wouldn't have to be new'ed; I think DFL (very .Net like form library for D) does this.
Jun 30 2007