View mode: basic / threaded / horizontal-split · Log in · Help
January 16, 2011
Re: Assigning Interface to Object
Stewart Gordon <smjg_1998@yahoo.com> wrote:

> Of course, if the interface declares an opEquals, it's a whole different  
> story....

It is? Can't seem to get it to work here, and I get the same errors you  
get.


-- 
Simen
January 17, 2011
Re: Assigning Interface to Object
On Sun, 16 Jan 2011 08:11:45 -0500, Stewart Gordon <smjg_1998@yahoo.com>  
wrote:

> On 16/01/2011 08:23, "Jérôme M. Berger" wrote:
>> Stewart Gordon wrote:
>>> On 15/01/2011 17:44, Steven Schveighoffer wrote:
>>> <snip>
>>>> Which unnecessarily complicates things. For example, you can't compare
>>>> two interfaces (try it!).
>>>
>>> ?
>> interface I {}
>>
>> ...
>>
>> I a = ...;
>> I b = ...;
>>
>> if (a == b) //<-- ERROR
>
>
> 1.065: compiles without error, though it seems to be equivalent to is
> 2.051: it's really weird
> ----------
> C:\Users\Stewart\Documents\Programming\D\Tests>dmd interface_equals.d
> interface_equals.d(7): Error: function object.opEquals (Object lhs,  
> Object rhs)
> is not callable using argument types (I,I)
> interface_equals.d(7): Error: cannot implicitly convert expression (a)  
> of type i
> nterface_equals.I to object.Object
> interface_equals.d(7): Error: cannot implicitly convert expression (b)  
> of type i
> nterface_equals.I to object.Object
> ----------
>
> Of course, if the interface declares an opEquals, it's a whole different  
> story....

Nope.  try it:

interface I { bool opEquals(I other); }

I a;
I b;

a == b; // same error.

The problem is that when TDPL was implemented, (Object)a == (Object)b was  
redefined from a.opEquals(b) to object.opEquals(a, b), where object is the  
module object.

That function's signature looks like this:

bool opEquals(Object lhs, Object rhs);

For some reason the compiler tries to do the same thing with interfaces,  
but of course, there is no opEquals for your specific interface in  
object.  Even if there was, you'd likely get an overload error.

This would be easily resolved if interfaces were known to be Objects.

-Steve
January 17, 2011
Re: Assigning Interface to Object
Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> Nope.  try it:
>
> interface I { bool opEquals(I other); }
>
> I a;
> I b;
>
> a == b; // same error.
>
> The problem is that when TDPL was implemented, (Object)a == (Object)b  
> was redefined from a.opEquals(b) to object.opEquals(a, b), where object  
> is the module object.
>
> That function's signature looks like this:
>
> bool opEquals(Object lhs, Object rhs);
>
> For some reason the compiler tries to do the same thing with interfaces,  
> but of course, there is no opEquals for your specific interface in  
> object.  Even if there was, you'd likely get an overload error.
>
> This would be easily resolved if interfaces were known to be Objects.

There's another way that should work, replacing the global opEquals in
object.di with this:


equals_t opEquals(T, U)(T lhs, U rhs)
    if ((is(T == class) || is(T == interface)) && (is(U == class) || is(U  
== interface)))
{
    if (lhs is rhs)
        return true;
    if (lhs is null || rhs is null)
        return false;
    static if (__traits(compiles,{lhs.opEquals(rhs);}))
    {
        if (typeid(lhs) == typeid(rhs))
            return lhs.opEquals(rhs);
        static if (__traits(compiles,{lhs.opEquals(rhs) &&  
rhs.opEquals(lhs);}))
        {
            return lhs.opEquals(rhs) &&
                rhs.opEquals(lhs);
        }
        else static assert( false, T.stringof ~ " cannot be compared to a  
" ~ U.stringof );
    }
    else static assert( false, T.stringof ~ " cannot be compared to a " ~  
U.stringof );
}


There are some problems, however. This generates bloat, as instantiations
are created for each combination of types compared. Also, it is only tested
for a few simple cases.

-- 
Simen
January 20, 2011
Re: Assigning Interface to Object
"This would be easily resolved if interfaces were known to be Objects. "

But shouldnt this be the case, because there would be nothing called as an
Interface which can be pointed to; it would be an Object which is implementing an
interface which is being pointed to. So shouldnt Interfaces be Objects too.
Otherwise, wouldnt it defeat the purpose of having Object as the base class for
everything.

Thanks
Mandeep
January 20, 2011
Re: Assigning Interface to Object
> interface I {}
>
> ...
>
> I a = ...;
> I b = ...;
>
> if (a == b) //<-- ERROR

"1.065: compiles without error, though it seems to be equivalent to is
2.051: it's really weird "

I would guess this should be filed as a bug then.

Thanks
Mandeep
January 20, 2011
Re: Assigning Interface to Object
On 01/20/11 01:01, Mandeep Singh Brar wrote:
> "This would be easily resolved if interfaces were known to be Objects. "
> 
> But shouldnt this be the case, because there would be nothing called as an
> Interface which can be pointed to; it would be an Object which is implementing an
> interface which is being pointed to. So shouldnt Interfaces be Objects too.
> Otherwise, wouldnt it defeat the purpose of having Object as the base class for
> everything.
> 
> Thanks
> Mandeep

There are actually Interfaces which don't necessarily imply inheritance
from Object.  The canonical example being IUnknown and it's own
descendants, used for interacting with COM libraries.  Another example
-- as I understand the implementation at least -- are 'extern(C++)'
interfaces, which are really API declarations for C++ classes.

That said, these are special cases, and I would expect the assertion
that interface <- Object to be true in all other cases.

-- Chris N-S
January 20, 2011
Re: Assigning Interface to Object
Mandeep Singh Brar <mandeep@brars.co.in> wrote:

> "This would be easily resolved if interfaces were known to be Objects. "
>
> But shouldnt this be the case, because there would be nothing called as  
> an
> Interface which can be pointed to; it would be an Object which is  
> implementing an
> interface which is being pointed to. So shouldnt Interfaces be Objects  
> too.
> Otherwise, wouldnt it defeat the purpose of having Object as the base  
> class for
> everything.

Object is only the base class for all D classes. Interfaces may also
represent COM objects or C++ classes, which are not subclasses of Object.


-- 
Simen
January 20, 2011
Re: Assigning Interface to Object
> Object is only the base class for all D classes. Interfaces may also
> represent COM objects or C++ classes, which are not subclasses of
Object.

Can't the compiler check if it is a normal D interface and then allow
(implicit) casts to Object?
January 20, 2011
Re: Assigning Interface to Object
On Thu, 20 Jan 2011 02:01:26 -0500, Mandeep Singh Brar  
<mandeep@brars.co.in> wrote:

> "This would be easily resolved if interfaces were known to be Objects. "
>
> But shouldnt this be the case, because there would be nothing called as  
> an
> Interface which can be pointed to; it would be an Object which is  
> implementing an
> interface which is being pointed to. So shouldnt Interfaces be Objects  
> too.
> Otherwise, wouldnt it defeat the purpose of having Object as the base  
> class for
> everything.

The issue is COM interfaces.  What bugs me about it is, whether an  
interface derives from IUnknown is known at compile time.  I don't think  
it's possible to define an interface that *doesn't* derive from IUnknown  
that is not a D Object.  I believe the compiler even handles IUnknown  
interfaces differently.

I think the problem is that COM support was added when compile-time  
functionality was in its infancy.  There are quite a few legacy problems  
due to that.  For instance, the builtin array sort routine does not use  
compile-time information.

It would be nice to fix this problem, but I'm not sure how willing Walter  
is to do it.  For sure, we need a solution to the opEquals problem.

-Steve
January 21, 2011
Re: Assigning Interface to Object
Speaking of COM.. has anyone successfully used COM interfaces in D2?
I'm asking because a few months ago I gave them a try but I kept
having random access violations. And I *do* mean random, sometimes
adding/removing print statements that don't even touch the state of
the program would cause a crash. I couldn't even transfer the D1 COM
example to D2, even though the D1 example works fine.

I might have to investigate this further soon.
1 2 3
Top | Discussion index | About this forum | D home