Thread overview
Static operator overloads (again)
Sep 01, 2008
Giles Bathgate
Sep 02, 2008
Giles Bathgate
Sep 02, 2008
Giles Bathgate
Sep 02, 2008
Christopher Wright
Sep 03, 2008
Giles Bathgate
Sep 04, 2008
Christopher Wright
Sep 04, 2008
Giles Bathgate
Sep 04, 2008
Denis Koroskin
Sep 05, 2008
Christopher Wright
September 01, 2008
I am trying to translate the following C# code into D

     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;
            }

        }

void main()
{
    Test T = null;
    Test B = null;
    T += B;
}

Whilst leaving the syntax of main() untouched.

September 01, 2008
On Mon, Sep 1, 2008 at 9:11 AM, Giles Bathgate <gilesbathgate@gmail.com>wrote:

> I am trying to translate the following C# code into D
>
>     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;
>            }
>
>        }
>
> void main()
> {
>    Test T = null;
>    Test B = null;
>    T += B;
> }
>
> Whilst leaving the syntax of main() untouched.
>
>
Long story short: I really don't think you can.  Operator overloading in D can only be performed as nonstatic methods of user-defined types.  Since a virtual method call requires that the object you're calling it on be non-null (so that you can get the vtable), you can't use overloaded operators on null references.


September 02, 2008
Jarrett Billingsley Wrote:

> Long story short: I really don't think you can.  Operator overloading in D
> can only be performed as nonstatic methods of user-defined types.  Since > a virtual method call requires that the object you're calling it on be
> non-null (so that you can get the vtable), you can't use overloaded
> operators on null references.

But static operator overloads are possible in D.
September 02, 2008
Giles Bathgate Wrote:

> But static operator overloads are possible in D.

Example:

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);

}

The problem with this though is that there is no access to the lvalue t this is because t+=b; translates to Text.opAddAssign(b);  I would like to propose a feature that given the operator overload:

 public static Test opAddAssign(Test lvalue, Test rvalue)
 {
 }

then

t += b;

would translate to:

Test.opAddAssign(t,b);

I really think this would benefit the language, without breaking anything since the compiler can distinguish between single and double parameter static operator overloads.


September 02, 2008
Giles Bathgate wrote:
> Giles Bathgate Wrote:
> 
>> But static operator overloads are possible in D.
> 
> Example:
> 
> 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);
> 
> }
> 
> The problem with this though is that there is no access to the lvalue t this is because t+=b; translates to Text.opAddAssign(b);  I would like to propose a feature that given the operator overload:
> 
>  public static Test opAddAssign(Test lvalue, Test rvalue)
>  {
>  }
> 
> then
> 
> t += b; 
> 
> would translate to: 
> 
> Test.opAddAssign(t,b);
> 
> I really think this would benefit the language, without breaking anything since the compiler can distinguish between single and double parameter static operator overloads.

I don't particularly think that it would benefit the language. There's no difference between a method call and using an operator overload. If you find yourself doing a lot of null checks, you might want to check out the Null Object pattern.

I don't think that having operator overloads be static is such a bad thing, though it prevents you from overloading operators with types. (downs has some interesting examples to this effect...)
September 03, 2008
Christopher Wright Wrote:

> I don't particularly think that it would benefit the language. There's no difference between a method call and using an operator overload. If you find yourself doing a lot of null checks, you might want to check out the Null Object pattern.

The point is when I write

t += b;

I don't expect a null reference exception. With operator overloads the only way (that made sense to me) to achieve this was to make the opCatAssign method static, but then my dilemma is that I no longer have an access to the value of t within the opCatAssign method call.
September 04, 2008
Giles Bathgate wrote:
> Christopher Wright Wrote:
> 
>> I don't particularly think that it would benefit the language. There's no difference between a method call and using an operator overload. If you find yourself doing a lot of null checks, you might want to check out the Null Object pattern.
> 
> The point is when I write 
> 
> t += b;
> 
> I don't expect a null reference exception. With operator overloads the only way (that made sense to me) to achieve this was to make the opCatAssign method static, but then my dilemma is that I no longer have an access to the value of t within the opCatAssign method call.

On the other hand, what about subclasses? They can't override the behavior of an operator overload, if operator overloading uses static methods. You're reduced to writing your overloads as:

class Foo
{
	static Foo opAddAssign (Foo left, Foo right)
	{
		return left.addAssign(right);
	}
}

So your proposal eliminates two valid use cases and breaks existing syntax and expectations. The only benefit you get is being able to use null in an operator overload, which is also an unexpected change from the existing system.

Just use the Null Object pattern. It's intended to solve exactly the sort of problem you have, and it works with methods as well.
September 04, 2008
Christopher Wright Wrote:

> On the other hand, what about subclasses? They can't override the behavior of an operator overload, if operator overloading uses static methods. You're reduced to writing your overloads as:
> 
> class Foo
> {
> 	static Foo opAddAssign (Foo left, Foo right)
> 	{
> 		return left.addAssign(right);
> 	}
> }
> 

I don't understand your example. It was my understanding that static methods cannot be overridden. (there is no vtable entry for a static method)

Maybe you thought that I an requesting for D's implementation of operator overloads to ONLY use static methods?
September 04, 2008
On Thu, 04 Sep 2008 13:47:20 +0400, Giles Bathgate <gilesbathgate@gmail.com> wrote:

> Christopher Wright Wrote:
>
>> On the other hand, what about subclasses? They can't override the
>> behavior of an operator overload, if operator overloading uses static
>> methods. You're reduced to writing your overloads as:
>>
>> class Foo
>> {
>> 	static Foo opAddAssign (Foo left, Foo right)
>> 	{
>> 		return left.addAssign(right);
>> 	}
>> }
>>
>
> I don't understand your example. It was my understanding that static methods cannot be overridden. (there is no vtable entry for a static method)
>

Indeed, static methods can't be overriden. That's why you end up writing something like this to get polymorphism in C#.

> Maybe you thought that I an requesting for D's implementation of operator overloads to ONLY use static methods?

No, but what is the real difference between two, apart from ability to pass null pointers which is a bad design anyway? It is redundant. I think it should be removed from language at all.
September 05, 2008
Giles Bathgate wrote:
> Christopher Wright Wrote:
> 
>> On the other hand, what about subclasses? They can't override the behavior of an operator overload, if operator overloading uses static methods. You're reduced to writing your overloads as:
>>
>> class Foo
>> {
>> 	static Foo opAddAssign (Foo left, Foo right)
>> 	{
>> 		return left.addAssign(right);
>> 	}
>> }
>>
> 
> I don't understand your example. It was my understanding that static methods cannot be overridden. (there is no vtable entry for a static method)

That is my point. Static methods cannot be overridden. I want virtual operator overloads.

> Maybe you thought that I an requesting for D's implementation of operator overloads to ONLY use static methods?

So your suggestion is to convert:

{{{
MyClass instance1, instance2;
auto instance3 = instance1 + instance2;
}}}

to:
{{{
MyClass instance1, instance2;
MyClass instance3;
static if (isStaticMethod!(MyClass.opAdd))
	instance3 = MyClass.opAdd(instance1, instance2);
else
	instance3 = instance1.opAdd(instance2);
}}}

I don't see anything wrong with this suggestion. But I just don't see any compelling reason for it. I'm not getting off my chair to patch dmd to support this.