View mode: basic / threaded / horizontal-split · Log in · Help
March 08, 2005
Compiler generated opCmp(Object)
Since it would be, in the general case, meaningless to compare disparate 
types, why cannot the compiler automatically generate opCmp(Object) from 
opCmp(MyType) (the latter would have to exist, of course), and save 
people having to do the first of the following two example ones (from 
class std.openrj.Field) every time:


 int opCmp(Object rhs)
 {
   Field f = cast(Field)(rhs);

   if(null === f)
   {
     throw new InvalidTypeException("Attempt to compare a Field with an 
instance of another type");
   }

   return opCmp(f);
 }

 int opCmp(Field rhs)
 {
   int res;

   if(this === rhs)
   {
     res = 0;
   }
   else
   {
     res = std.string.cmp(m_name, rhs.m_name);

     if(0 == res)
     {
       res = std.string.cmp(m_value, rhs.m_value);
     }
   }

   return res;
 }


Anyone reasons against??
March 08, 2005
Re: Compiler generated opCmp(Object)
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message
news:d0jbq1$1a67$1@digitaldaemon.com...
> Since it would be, in the general case, meaningless to compare disparate
> types, why cannot the compiler automatically generate opCmp(Object) from
> opCmp(MyType) (the latter would have to exist, of course), and save
> people having to do the first of the following two example ones (from
> class std.openrj.Field) every time:

Because it would be a special case for opCmp, and no other virtual function
would work like that. I think that would be surprising behavior.

>   int opCmp(Object rhs)
>   {
>     Field f = cast(Field)(rhs);
>
>     if(null === f)
>     {
>       throw new InvalidTypeException("Attempt to compare a Field with an
> instance of another type");
>     }
>
>     return opCmp(f);
>   }
>
>   int opCmp(Field rhs)
>   {
>     int res;
>
>     if(this === rhs)
>     {
>       res = 0;
>     }
>     else
>     {
>       res = std.string.cmp(m_name, rhs.m_name);
>
>       if(0 == res)
>       {
>         res = std.string.cmp(m_value, rhs.m_value);
>       }
>     }
>
>     return res;
>   }

I'd just write it as:

   int opCmp(Object o)
   {    Field rhs = cast(Field)o;
        int result = 0;
       if (rhs)
       {
       if (this == rhs)
           result = 1;
       else
       {    result = std.string.cmp(m_name, rhs.m_name);
           if (result == 0)
               result = std.string.cmp(m_value, rhs.m_value);
       }
       }
       return result;
  }

It's not necessary to write the opCmp(Field). One could replace the if(rhs)
with assert(rhs). Since tripping this would be a programming error, not a
user input error, shouldn't it be a contract rather than a custom exception?
March 08, 2005
Re: Compiler generated opCmp(Object)
Walter wrote:

> I'd just write it as:
> 
>     int opCmp(Object o)
>     {    Field rhs = cast(Field)o;
>          int result = 0;
>         if (rhs)
>         {
>         if (this == rhs)
>             result = 1;
>         else
>         {    result = std.string.cmp(m_name, rhs.m_name);
>             if (result == 0)
>                 result = std.string.cmp(m_value, rhs.m_value);
>         }
>         }
>         return result;
>    }
> 
> It's not necessary to write the opCmp(Field). One could replace the if(rhs)
> with assert(rhs). Since tripping this would be a programming error, not a
> user input error, shouldn't it be a contract rather than a custom exception?

Depends on the D definition of comparing with null, I suppose ?
In some other languages, this operation is *defined* as "false".

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#equals(java.lang.Object)
> For any non-null reference value x, x.equals(null) should return false.


Q: Wouldn't the '==' shortcut above belong in opEquals instead ?
(since aren't you looping over the same string twice, otherwise ?)

And of course, Matthew will probably go ballistic over the use
of  "int" and 0 and 1, and if with non-bool types, and such... :-D


Here's how I wrote it, for a String class:

> 	int opEquals(Object o)
> 	{
> 		if (this is o)
> 			return true;
> 		String string = cast(String) o;
> 		if (string is null)
> 			return false;
> 
> 		return this.str == string.str;
> 	}
> 
> 	int opCmp(Object o)
> 	{
> 		if (this is o)
> 			return true;
> 		String string = cast(String) o;
> 		if (string is null)
> 			return false;
> 
> 		return std.string.cmp(this.str, string.str);
> 	}
> 

http://www.algonet.se/~afb/d/javastring/String.d

--anders
March 08, 2005
Re: Compiler generated opCmp(Object)
Anders F Björklund wrote:

> Here's how I wrote it, for a String class:
> 
>>     int opEquals(Object o)
>>     {
>>         if (this is o)
>>             return true;
>>         String string = cast(String) o;
>>         if (string is null)
>>             return false;
>>
>>         return this.str == string.str;
>>     }
>>
>>     int opCmp(Object o)
>>     {
>>         if (this is o)
>>             return true;
>>         String string = cast(String) o;
>>         if (string is null)
>>             return false;
>>
>>         return std.string.cmp(this.str, string.str);
>>     }

Darnit, copy and paste striketh again!

    int opCmp(Object o)
    {
         if (this is o)
             return 0;
         String string = cast(String) o;
         if (string is null)
             assert(0);

         return std.string.cmp(this.str, string.str);
     }

Sorry :-(

--anders
March 08, 2005
Re: Compiler generated opCmp(Object)
Matthew wrote:
> Since it would be, in the general case, meaningless to compare disparate 
> types, why cannot the compiler automatically generate opCmp(Object) from 
> opCmp(MyType) (the latter would have to exist, of course), and save 
> people having to do the first of the following two example ones (from 
> class std.openrj.Field) every time:

To half of us, it remains really just a question of why opCmp(Object) 
has to exist at all.  Did you see this thread a while back?

http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/10558

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
March 09, 2005
Re: Compiler generated opCmp(Object)
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message 
news:d0kn8d$2tji$1@digitaldaemon.com...
> Matthew wrote:
>> Since it would be, in the general case, meaningless to compare 
>> disparate types, why cannot the compiler automatically generate 
>> opCmp(Object) from opCmp(MyType) (the latter would have to exist, of 
>> course), and save people having to do the first of the following two 
>> example ones (from class std.openrj.Field) every time:
>
> To half of us, it remains really just a question of why opCmp(Object) 
> has to exist at all.  Did you see this thread a while back?
>
> http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/10558

Alas, no. In order to catch up I had to do a wholesale "Mark Read".

I'll check it out.
Top | Discussion index | About this forum | D home