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 next 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
prev sibling next sibling parent reply Giles Bathgate <gilesbathgate gmail.com> writes:
 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."
I don't know what you mean by this I tried public class Test { public char[] Name; public Test opAddAssign(Test value) { writefln(value.Name); writefln(Test.Name); //... } } It didnt work
 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. 
DFL huh? there is another thing that went under the radar... Its a shame there is no "distribution" of D Anyway I am not looking for a solution to the problem of how to create a multicast delegate class in D I am trying to solve the meta problem, of how to access an lvalue in a static operator overload.
Jul 05 2007
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Giles Bathgate wrote

 how to access an lvalue in a static operator overload.
operators declared `static' can only access entities that are actual parameters or declared `static' too. Therefore change | public char[] Name; to public static char[] Name; Or as a complete example: public class Test { static char[] baseName = "Test"; char[] name; static void opAddAssign(Test value) { writefln(value.name); Test.baseName~= ".".dup; baseName~= value.name.dup; } static void opCall(){ writefln( ":", baseName); } } void main() { Test b = new Test(); b.name = "foo"; Test += b; Test(); Test t; t(); } import std.stdio; Or in other words: for the entities of a class that are declared `static' the D-compiler automatically establishes a singleton and that singleton can be accessed 1) by the name of the class or 2) every instance of the class So: your questions
 'should static operator overloads even be allowed?' and if they
 were to be allowed should they not have two arguments?
have the answers yes and no respectively. -manfred
Jul 05 2007
next sibling parent GilesBathgate <gilesbathgate gmail.com> writes:
 operators declared `static' can only access entities that are actual 
 parameters or declared `static' too. 
Exactly and since the lvalue is not a parameter then I cannot access it! The language dosen't support what I want to do, and I am preposing it should because its very useful if not essential to be able to access the lvalue in an operator overload.
Jul 05 2007
prev sibling parent reply GilesBathgate <gilesbathgate gmail.com> writes:
 Or in other words:
 for the entities of a class that are declared `static' the D-compiler 
 automatically establishes a singleton and that singleton can be 
 accessed 
 1) by the name of the class or
 2) every instance of the class
Yeah I know, I am a programmer. If you can translate this C# code into D I will give you a medal public class Test { public string Name; public static Test operator +(Test lvalue, Test rvalue) { if (lvalue == null) { lvalue = new Test(); lvalue.Name = "foo"; } if (rvalue == null) { rvalue = new Test(); rvalue.Name = "bar"; } Console.Write(lvalue.Name); Console.Write(rvalue.Name); return rvalue; } } static void Main(string[] args) { Test T = null; Test B = null; T += B; }
Jul 05 2007
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 05 Jul 2007 15:24:34 -0400, GilesBathgate wrote:


 If you can translate this C# code into D I will give you a medal
Where do I apply for the medal :-) import std.stdio; class Test { string Name; static Test opAddAssign(ref Test lvalue, ref Test rvalue) { if (lvalue is null) { lvalue = new Test(); lvalue.Name = "foo"; } if (rvalue is null) { rvalue = new Test(); rvalue.Name = "bar"; } writefln("%s", lvalue.Name); writefln("%s", rvalue.Name); return rvalue; } } void main() { Test T; Test B; Test.opAddAssign(T,B); } -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jul 05 2007
parent reply Giles Bathgate <gilesbathgate gmail.com> writes:
 void main()
 {
     Test T;
     Test B;
     Test.opAddAssign(T,B);
 }
Cheaters do not win medals. Its hardly an operator overload if you have to write Test.opAddAssign(T,B); instead of T += B; sorry. Do you see my point yet?
Jul 06 2007
parent reply Derek Parnell <derek psych.ward> writes:
On Fri, 06 Jul 2007 05:46:01 -0400, Giles Bathgate wrote:

 void main()
 {
     Test T;
     Test B;
     Test.opAddAssign(T,B);
 }
Cheaters do not win medals. Its hardly an operator overload if you have to write Test.opAddAssign(T,B); instead of T += B; sorry. Do you see my point yet?
Hang on a minute, all you asked for was someone to "translate" the C# code into D. And that is what I did. You did not specify that the resultant translation must use the "+=" operator. Do you see my point? <G> -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jul 06 2007
parent David L. Davis <SpottedTiger yahoo.com> writes:
Give the man his medal! :)  (It's not creating, if you follow the rules)

Derek Parnell Wrote:

 On Fri, 06 Jul 2007 05:46:01 -0400, Giles Bathgate wrote:
 
 void main()
 {
     Test T;
     Test B;
     Test.opAddAssign(T,B);
 }
Cheaters do not win medals. Its hardly an operator overload if you have to write Test.opAddAssign(T,B); instead of T += B; sorry. Do you see my point yet?
Hang on a minute, all you asked for was someone to "translate" the C# code into D. And that is what I did. You did not specify that the resultant translation must use the "+=" operator. Do you see my point? <G> -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jul 06 2007
prev sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
GilesBathgate wrote

 If you can translate this C# code into D I will give you a medal
As some replies might have shown, it is unclear what you might mean with "translate". <elaboration> In a game with main language german a german tourist in China asks a passerby "Sprechen Sie deutsch?", which means "Do you speak german?" The correct _translation_ to english would of course be "Do you speak german?" But why would a native english speaker ask some one in China whether he speaks german? So: the correct _transduction_ would be "Do you speak english?" Because you are a programmer this elaboration should be enough to put you on the tip of the iceberg. </elaboration> -manfred
Jul 08 2007
prev sibling parent reply Giles Bathgate <gilesbathgate gmail.com> writes:
 DFL (very .Net like form library for D) does this. 
Is DFL open source?
Jul 06 2007
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Giles Bathgate wrote:
 DFL (very .Net like form library for D) does this. 
Is DFL open source?
http://www.dprogramming.com/dfl.php It says the download contains source, but doesn't mention the license (I didn't download it). Though I guess the forum being hosted on dsource.org might be a clue that it's probably open source.
Jul 06 2007
parent reply Giles Bathgate <gilesbathgate gmail.com> writes:
 http://www.dprogramming.com/dfl.php
 It says the download contains source, but doesn't mention the license (I
didn't download it). Though I guess the forum being hosted on 
 dsource.org might be a clue that it's probably open source.
I did download it and I couldn't find the source.
Jul 06 2007
next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Giles Bathgate wrote:
 http://www.dprogramming.com/dfl.php
 It says the download contains source, but doesn't mention the license (I
didn't download it). Though I guess the forum being hosted on 
 dsource.org might be a clue that it's probably open source.
I did download it and I couldn't find the source.
It's in import\dfl
Jul 06 2007
prev sibling parent "Chris Miller" <chris dprogramming.com> writes:
On Fri, 06 Jul 2007 10:58:35 -0400, Giles Bathgate  
<gilesbathgate gmail.com> wrote:

 http://www.dprogramming.com/dfl.php
 It says the download contains source, but doesn't mention the license  
 (I didn't download it). Though I guess the forum being hosted on
 dsource.org might be a clue that it's probably open source.
I did download it and I couldn't find the source.
If you used the installer you can find it from your start menu. Otherwise, it's generally at C:\dmd\import\dfl Examples can be found there too, or at C:\dmd\packages\dfl\examples
Jul 06 2007