www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interface problems

reply Mandeep Singh Brar <mandeep brars.co.in> writes:
Hi,

Not a question but just raising a concern i am facing again and again. The
current implementation of interfaces seem to be creating a number of problems.

I am not able to:

- find indexOf interface in an interface range using std.algorithm.
- compare interface objects
- assign interface to generic objects.

Does COM support warrant so much weight so as to break the interfaces
implementation from D1 and all other languages. What is the way to get this
addressed (is there a possibility at all).

Thanks
Mandeep
Jan 25 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Mandeep Singh Brar:

 I am not able to:
 
 - find indexOf interface in an interface range using std.algorithm.
I don't understand. Please explain better.
 - compare interface objects
What kind of comparisons do you need to perform and why?
 - assign interface to generic objects.
Why do you need to do this? Bye, bearophile
Jan 25 2011
parent reply Mandeep Singh Brar <mandeep brars.co.in> writes:
Mandeep Singh Brar:

 I am not able to:

 - find indexOf interface in an interface range using std.algorithm.
 I don't understand. Please explain better.
In the following snippet: Interface interfaceA{} class C:interfaceA{} class D:interfaceA{} interfaceA[] registry; register(interfaceA a) { registry ~= a; } unregister(interfaceA a) {idx = registry.indexOf(a); registry.replace(idx, idx+1, null); } In the above statement indexOf does not work.
 - compare interface objects
 What kind of comparisons do you need to perform and why?
Simple comparisons like in the below snippet class A { interfaceTest myInstance; setInstance(interfaceTest interfaceInstance) { if(myInstance != interfaceInstance) //does not work { updateMyInstance; doStuff; } } }
 - assign interface to generic objects.
 Why do you need to do this?
Just store various types of objects in a generic way like Object[] objects; objects ~= objA; objects~= interB and so on. I cant use Variant because interface can not be assigned to Variants and i cant use Objects too.
 Bye,
 bearophile
Thanks Mandeep
Jan 25 2011
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 26.01.2011 8:12, Mandeep Singh Brar wrote:
 Mandeep Singh Brar:

 I am not able to:

 - find indexOf interface in an interface range using std.algorithm.
 I don't understand. Please explain better.
In the following snippet: Interface interfaceA{} class C:interfaceA{} class D:interfaceA{} interfaceA[] registry; register(interfaceA a) { registry ~= a; } unregister(interfaceA a) {idx = registry.indexOf(a); registry.replace(idx, idx+1, null); } In the above statement indexOf does not work.
You should use 'is' for such kind of thing. The problem is that == uses opEquals or opCmp, there is no such thing for interfaces AFIKT. But for every pointer like type we can check if they are the same with 'is'. Here is your fixed snippet : import std.algorithm; import std.array; interface interfaceA{} class C:interfaceA{} class D:interfaceA{} interfaceA[] registry; void register(interfaceA a) { registry ~= a; } void unregister(interfaceA a) { auto idx = indexOf!"a is b"(registry,a); registry.replace(idx,idx+1, null); } void main(){ auto b = new D(); register(new C()); register(b); unregister(b); }
 - compare interface objects
Yeah, here it sucks. 'is' is your best chance ;)
 What kind of comparisons do you need to perform and why?
Simple comparisons like in the below snippet class A { interfaceTest myInstance; setInstance(interfaceTest interfaceInstance) { if(myInstance != interfaceInstance) //does not work { updateMyInstance; doStuff; } } }
Here just use '!is ' instead of != [snip]
        Just store various types of objects in a generic way like
             Object[] objects;
             objects ~= objA; objects~= interB and so on.

        I cant use Variant because interface can not be assigned to Variants
and i
 cant use Objects too.
If you need to pile up different interfaces (no occasional Object ). The workaround would be to inherit all your interfaces from a common base like: interface Base{} interface A: Base{...} interface B: Base{...} class CA: A{.. } Base[] pile; pile ~= new CA();
 Bye,
 bearophile
Thanks Mandeep
-- Dmitry Olshansky
Jan 26 2011
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 26 Jan 2011 05:12:39 -0500, Dmitry Olshansky  
<dmitry.olsh gmail.com> wrote:

 On 26.01.2011 8:12, Mandeep Singh Brar wrote:
 Mandeep Singh Brar:

 I am not able to:

 - find indexOf interface in an interface range using std.algorithm.
 I don't understand. Please explain better.
In the following snippet: Interface interfaceA{} class C:interfaceA{} class D:interfaceA{} interfaceA[] registry; register(interfaceA a) { registry ~= a; } unregister(interfaceA a) {idx = registry.indexOf(a); registry.replace(idx, idx+1, null); } In the above statement indexOf does not work.
You should use 'is' for such kind of thing. The problem is that == uses opEquals or opCmp, there is no such thing for interfaces AFIKT. But for every pointer like type we can check if they are the same with 'is'.
This is hardly a solution. He wants to do value comparison, not identity comparison. The real fix is to make interface assume it is an Object, so it can be implicitly cast to Object, and find another way to implement COM interfaces. The COM interface "hack" is way outdated and extremely harmful, esp. on OS' who *don't use COM*! I can't see how the benefits it has outweigh the problems it causes. -Steve
Jan 26 2011
parent reply Stanislav Blinov <blinov loniir.ru> writes:
26.01.2011 16:54, Steven Schveighoffer пишет:
 This is hardly a solution.  He wants to do value comparison, not 
 identity comparison.

 The real fix is to make interface assume it is an Object, so it can be 
 implicitly cast to Object, and find another way to implement COM 
 interfaces.  The COM interface "hack" is way outdated and extremely 
 harmful, esp. on OS' who *don't use COM*!  I can't see how the 
 benefits it has outweigh the problems it causes.
The recent discussion in D group about destructor order brought me to yet another question about interfaces. Currently, functions that should accept classes as parameters, e.g. clear(), accept interfaces as well: void clear(T)(T obj) if (is(T == class)) // note the constraint { /*...*/ } interface I {} class A : I {} void main() { I a = new A; // note that typeof(a) is I, not A clear(a); } This compiles. But raises a question: how come? If it is assumed that a reference to interface is not necessarily a D class instance, then it shouldn't. The fact that it compiles even more ambiguates the purpose and usage of interfaces. I agree with Steven. Having a support for COM, CORBA and so on in the language is great, but wouldn't it be better to specify it explicitly? Maybe solidify the usage of 'extern' keyword? interface D {} // instances are guaranteed to be D Objects extern interface E {} // instances may or may not be D Objects (COM and alike) I mean, it's already there in the language and is described in 'Interfacing to C++' in the documentation. Though currently, extern interfaces are accepted by is(T == class) constraint as well.
Jan 27 2011
next sibling parent reply Mandeep Singh Brar <mandeep brars.co.in> writes:
26.01.2011 16:54, Steven Schveighoffer пишет:
 This is hardly a solution.  He wants to do value comparison, not
 identity comparison.

 The real fix is to make interface assume it is an Object, so it can be
 implicitly cast to Object, and find another way to implement COM
 interfaces.  The COM interface "hack" is way outdated and extremely
 harmful, esp. on OS' who *don't use COM*!  I can't see how the
 benefits it has outweigh the problems it causes.
The recent discussion in D group about destructor order brought me to yet another question about interfaces. Currently, functions that should accept classes as parameters, e.g. clear(), accept interfaces as well: void clear(T)(T obj) if (is(T == class)) // note the constraint { /*...*/ } interface I {} class A : I {} void main() { I a = new A; // note that typeof(a) is I, not A clear(a); } This compiles. But raises a question: how come? If it is assumed that a reference to interface is not necessarily a D class instance, then it shouldn't. The fact that it compiles even more ambiguates the purpose and usage of interfaces. I agree with Steven. Having a support for COM, CORBA and so on in the language is great, but wouldn't it be better to specify it explicitly? Maybe solidify the usage of 'extern' keyword? interface D {} // instances are guaranteed to be D Objects extern interface E {} // instances may or may not be D Objects (COM and alike) I mean, it's already there in the language and is described in 'Interfacing to C++' in the documentation. Though currently, extern interfaces are accepted by is(T == class) constraint as well. Second this thought. Interface IMHO are far too basic for a functionality tweak. Would also like to understand the way to raise such requests and take them to their logical conclusion. Regards Mandeep
Jan 27 2011
parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On 01/27/2011 09:27 PM, Mandeep Singh Brar wrote:
 26.01.2011 16:54, Steven Schveighoffer пишет:
 This is hardly a solution.  He wants to do value comparison, not
 identity comparison.

 The real fix is to make interface assume it is an Object, so it can be
 implicitly cast to Object, and find another way to implement COM
 interfaces.  The COM interface "hack" is way outdated and extremely
 harmful, esp. on OS' who *don't use COM*!  I can't see how the
 benefits it has outweigh the problems it causes.
The recent discussion in D group about destructor order brought me to yet another question about interfaces. Currently, functions that should accept classes as parameters, e.g. clear(), accept interfaces as well: void clear(T)(T obj) if (is(T == class)) // note the constraint { /*...*/ } interface I {} class A : I {} void main() { I a = new A; // note that typeof(a) is I, not A clear(a); } This compiles. But raises a question: how come? If it is assumed that a reference to interface is not necessarily a D class instance, then it shouldn't. The fact that it compiles even more ambiguates the purpose and usage of interfaces. I agree with Steven. Having a support for COM, CORBA and so on in the language is great, but wouldn't it be better to specify it explicitly? Maybe solidify the usage of 'extern' keyword? interface D {} // instances are guaranteed to be D Objects extern interface E {} // instances may or may not be D Objects (COM and alike) I mean, it's already there in the language and is described in 'Interfacing to C++' in the documentation. Though currently, extern interfaces are accepted by is(T == class) constraint as well. Second this thought. Interface IMHO are far too basic for a functionality tweak. Would also like to understand the way to raise such requests and take them to their logical conclusion. Regards Mandeep
There is bugzilla: d.puremagic.com/issues. You can create enhancement requests there along with bugreports.
Jan 27 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 27 Jan 2011 09:26:28 -0500, Stanislav Blinov <blinov loniir.ru>  
wrote:

 26.01.2011 16:54, Steven Schveighoffer пишет:
 This is hardly a solution.  He wants to do value comparison, not  
 identity comparison.

 The real fix is to make interface assume it is an Object, so it can be  
 implicitly cast to Object, and find another way to implement COM  
 interfaces.  The COM interface "hack" is way outdated and extremely  
 harmful, esp. on OS' who *don't use COM*!  I can't see how the benefits  
 it has outweigh the problems it causes.
The recent discussion in D group about destructor order brought me to yet another question about interfaces. Currently, functions that should accept classes as parameters, e.g. clear(), accept interfaces as well: void clear(T)(T obj) if (is(T == class)) // note the constraint { /*...*/ } interface I {} class A : I {} void main() { I a = new A; // note that typeof(a) is I, not A clear(a); } This compiles. But raises a question: how come? If it is assumed that a reference to interface is not necessarily a D class instance, then it shouldn't. The fact that it compiles even more ambiguates the purpose and usage of interfaces. I agree with Steven. Having a support for COM, CORBA and so on in the language is great, but wouldn't it be better to specify it explicitly? Maybe solidify the usage of 'extern' keyword? interface D {} // instances are guaranteed to be D Objects extern interface E {} // instances may or may not be D Objects (COM and alike) I mean, it's already there in the language and is described in 'Interfacing to C++' in the documentation. Though currently, extern interfaces are accepted by is(T == class) constraint as well.
It's because everywhere in the compiler, an interface is considered a class (I think even the type representing an interface is derived from the type representing class). Except one, and that's implicit casting to Object. My thought is, we already have extern(C++) interface, why not extern(COM) interface? But we could even leave the notion of interfaces deriving from IUnknown as COM interfaces and just have the compiler check if an interface derives from IUnknown. In fact, it *ALREADY DOES THIS* because it has to treat the layout of an IUnknown interface differently from another interface. The whole argument to have interfaces not derive from Object because of COM is standing on such poor footing that I can't see how it's taken this long to fix. -Steve
Jan 28 2011