Jump to page: 1 24  
Page
Thread overview
Differing implementations for a function in two interfaces
Apr 15, 2006
Lionello Lunesu
Apr 15, 2006
BCS
Apr 18, 2006
Lionello Lunesu
Apr 18, 2006
Ryan Steen
Apr 15, 2006
Ryan Steen
Apr 17, 2006
Lionello Lunesu
Apr 17, 2006
Ryan Steen
Apr 17, 2006
Lionello Lunesu
Apr 17, 2006
Ryan Steen
Apr 17, 2006
Lionello Lunesu
Apr 15, 2006
Hasan Aljudy
Apr 15, 2006
BCS
Apr 15, 2006
Hasan Aljudy
Apr 15, 2006
Hasan Aljudy
Apr 16, 2006
BCS
Apr 16, 2006
Hasan Aljudy
Apr 16, 2006
BCS
Apr 16, 2006
BCS
Apr 16, 2006
Hasan Aljudy
Apr 16, 2006
BCS
Apr 16, 2006
Derek Parnell
Apr 16, 2006
BCS
Apr 17, 2006
Lionello Lunesu
Apr 17, 2006
Ryan Steen
Apr 17, 2006
Hasan Aljudy
Apr 17, 2006
Lionello Lunesu
Apr 17, 2006
Ryan Steen
Apr 17, 2006
Lionello Lunesu
Apr 17, 2006
Ryan Steen
Apr 17, 2006
Ryan Steen
Apr 17, 2006
BCS
Apr 17, 2006
BCS
Apr 17, 2006
Ryan Steen
Apr 18, 2006
BCS
Apr 17, 2006
Lionello Lunesu
April 15, 2006
Hi,

Like the subject says, I have two interfaces that both declare some function, say "int get();", but in the class that implements these interfaces I'd like to differentiate between the two.

#interface IA {
#	int get();
#}

#interface IB {
#	int get();
#}

#class C : IA, IB {
#	int get() { return 1; }
#}

I would like to implement IA.get() differently from IB.get(), but is this even possible? Can't find anything on this in the docs.

Actually, what I'm trying to do is create multiple foreach/opApply's in one class, depending on which interface you use, specifically a wrapper for the sqlite "sqlite3_stmt" handle. I'd like to be able to iterate the rows in a result set, and the fields in a row.

At the moment I do this:

#// handle wrapper, RAII
#class Command {
#	sqlite3_stmt* stmt;
#	~this() { sqlite3_finalize(stmt); }
#	Result Execute() { return new Result(this); }
#}

#class Result {
#	Command cmd;
#	// this one iterates rows; does new ResultRow(cmd)
#	int opApply( int delegate(inout ResultRow) dg );
#}

#class ResultRow {
#	Command cmd;
#	// this one iterates fields; does new ResultField(cmd,fieldno);
#	int opApply( int delegate(inout ResultField) dg );
#}

#class ResultField {
#	Command cmd;
#	uint fieldno;
#}

This works just fine, but a lot of temporary objects are created, that don't really contain anything new, just a reference to the Command object. I would like to use interfaces instead:

#interface IResult {
#	// this one iterates rows
#	int opApply( int delegate(inout IResultRow) dg );
#}

#interface IResultRow {
#	// this one iterates fields
#	int opApply( int delegate(inout ResultField) dg );
#}

#// As before, since we need to keep track of the field index
#class ResultField {
#	Command cmd;
#	uint fieldno;
#}

#class Command : IResult, IResultRow {	// handle wrapper
#	sqlite3_stmt* stmt;
#	~this() { sqlite3_finalize(stmt); }
#	IResult Execute() { return cast(IResult)this; }
#	// this one iterates rows; does cast(IResultRow)this
#	int IResult.opApply( int delegate(inout IResultRow) dg );
#	// this one iterates fields; does new ResultField(this,fieldno)
#	int IResultRow.opApply( int delegate(inout IResultField) dg );
#}

Or is there a solution to this pattern I haven't thought of yet?

All comments are appreciated :)

L.
April 15, 2006
Lionello Lunesu wrote:
> #class Command : IResult, IResultRow {    // handle wrapper
...
> #    int IResult.opApply( int delegate(inout IResultRow) dg );
...
> #    int IResultRow.opApply( int delegate(inout IResultField) dg );
> #}

I actually rather like this syntax.  When I first started reading your post, this was precisely what I thought of as a possible general purpose solution.  The difficulty I see is in how to select which to use at call-time.  In your case, I see you use a simple `cast(Interface) object` to do so, which seems fair enough... but might there be another way to do the selection in simpler expressions?

# class Foo : IA, IB { ... } // IA and IB declare: int get();
#
# Foo obj = new Foo;
#
# // call IA.get()... ew
# (cast(IA) obj).get();
#
# // call IB.get()... eh
# obj.get@IB();
# // or
# obj@IB.get();
#
# // call IA.get()... erm
# obj.IA::get();

Just thinking.

-- Chris Nicholson-Sauls
April 15, 2006
In article <e1qem7$1lvs$1@digitaldaemon.com>, Lionello Lunesu says...

>#class Command : IResult, IResultRow {	// handle wrapper
>#	sqlite3_stmt* stmt;
>#	~this() { sqlite3_finalize(stmt); }
>#	IResult Execute() { return cast(IResult)this; }
>#	// this one iterates rows; does cast(IResultRow)this
>#	int IResult.opApply( int delegate(inout IResultRow) dg );
>#	// this one iterates fields; does new ResultField(this,fieldno)
>#	int IResultRow.opApply( int delegate(inout IResultField) dg );
>#}

I do not see the problem here because the opApply from the different interfaces do not have identical formal parameter lists. Therefore your code above is very vlose to the solution:

#class Command : IResult, IResultRow {	// handle wrapper
#	sqlite3_stmt* stmt;
#	~this() { sqlite3_finalize(stmt); }
#	IResult Execute() { return this; }
#	// this one iterates rows; does cast(IResultRow)this
#	int opApply( int delegate(inout IResultRow) dg );
#	// this one iterates fields; does new ResultField(this,fieldno)
#	int opApply( int delegate(inout IResultField) dg );
#}


April 15, 2006
In article <e1qgma$1ngm$1@digitaldaemon.com>, Chris Nicholson-Sauls says...
>
>Lionello Lunesu wrote:
>> #class Command : IResult, IResultRow {    // handle wrapper
>...
>> #    int IResult.opApply( int delegate(inout IResultRow) dg );
>...
>> #    int IResultRow.opApply( int delegate(inout IResultField) dg );
>> #}
>
>I actually rather like this syntax.  When I first started reading your post, this was precisely what I thought of as a possible general purpose solution.  The difficulty I see is in how to select which to use at call-time.  In your case, I see you use a simple `cast(Interface) object` to do so, which seems fair enough... but might there be another way to do the selection in simpler expressions?
>
Its not to clean but the use of aliases could be a solution to this and other problems, namely, now dose a class implement an interface with inherited functions?

Interface thingI
{
char[] getName()
char[] getType()
}

Class foo
{
char[] name(){...}
//no type
}

class bar : thingI
{
char[] type(){...}

alias name : thingI.getName;   //need not have the same name
alias type : thingI.getTypr;
}

but this would require that bug #52 be fixed so that DMD can distinguish between overloaded function

e.g.

int foo(int i){...}
int foo(char c){...}

auto fnp = &foo; // what type is fnp? DMD makes an arbitrary selection that is context dependent.




April 15, 2006
I didn't read/undertstand your entire post, but I think what you're trying to achieve here can already be achieved through polymorphism.

I think you just need to redeisgn the classes a little bit.

Lionello Lunesu wrote:
> Hi,
> 
> Like the subject says, I have two interfaces that both declare some function, say "int get();", but in the class that implements these interfaces I'd like to differentiate between the two.
> 
> #interface IA {
> #    int get();
> #}
> 
> #interface IB {
> #    int get();
> #}
> 
> #class C : IA, IB {
> #    int get() { return 1; }
> #}
> 
> I would like to implement IA.get() differently from IB.get(), but is this even possible? Can't find anything on this in the docs.
> 
> Actually, what I'm trying to do is create multiple foreach/opApply's in one class, depending on which interface you use, specifically a wrapper for the sqlite "sqlite3_stmt" handle. I'd like to be able to iterate the rows in a result set, and the fields in a row.
> 
> At the moment I do this:
> 
> #// handle wrapper, RAII
> #class Command {
> #    sqlite3_stmt* stmt;
> #    ~this() { sqlite3_finalize(stmt); }
> #    Result Execute() { return new Result(this); }
> #}
> 
> #class Result {
> #    Command cmd;
> #    // this one iterates rows; does new ResultRow(cmd)
> #    int opApply( int delegate(inout ResultRow) dg );
> #}
> 
> #class ResultRow {
> #    Command cmd;
> #    // this one iterates fields; does new ResultField(cmd,fieldno);
> #    int opApply( int delegate(inout ResultField) dg );
> #}
> 
> #class ResultField {
> #    Command cmd;
> #    uint fieldno;
> #}
> 
> This works just fine, but a lot of temporary objects are created, that don't really contain anything new, just a reference to the Command object. I would like to use interfaces instead:
> 
> #interface IResult {
> #    // this one iterates rows
> #    int opApply( int delegate(inout IResultRow) dg );
> #}
> 
> #interface IResultRow {
> #    // this one iterates fields
> #    int opApply( int delegate(inout ResultField) dg );
> #}
> 
> #// As before, since we need to keep track of the field index
> #class ResultField {
> #    Command cmd;
> #    uint fieldno;
> #}
> 
> #class Command : IResult, IResultRow {    // handle wrapper
> #    sqlite3_stmt* stmt;
> #    ~this() { sqlite3_finalize(stmt); }
> #    IResult Execute() { return cast(IResult)this; }
> #    // this one iterates rows; does cast(IResultRow)this
> #    int IResult.opApply( int delegate(inout IResultRow) dg );
> #    // this one iterates fields; does new ResultField(this,fieldno)
> #    int IResultRow.opApply( int delegate(inout IResultField) dg );
> #}
> 
> Or is there a solution to this pattern I haven't thought of yet?
> 
> All comments are appreciated :)
> 
> L.
April 15, 2006
In article <e1riem$3jd$1@digitaldaemon.com>, Hasan Aljudy says...
>
>I didn't read/undertstand your entire post, but I think what you're trying to achieve here can already be achieved through polymorphism.
>
>I think you just need to redeisgn the classes a little bit.
>
>
I don't think that would (always) work. Consider the following:

interface IA
{
int get();
}

interface IB
{
int get();
}

class C : IA, IB
{
public int i;
// illegal but ...
int get() { return i+1; } // get for IA
int get() { return i+2; } // get for IB
}

void main()
{
auto obj = new C;
IA a = obj;
IB b = obj;

obj.i = 0;
writef(a.get, \n);	// should print 1
writef(b.get, \n);	// should print 2

obj.i = 2;
writef(a.get, \n);	// should print 3
writef(b.get, \n);	// should print 4

}

Both "a" and "b" are actually pointing to obj but calls to "get" using them are supposed to differ. Some types of this problem could be handled by deriving classes from C but not when the interfaces must actually be dealing with the same object.

Cases like this could really happen if someone needs to implement two interfaces from different libraries in the same class.


April 15, 2006
BCS wrote:
> In article <e1riem$3jd$1@digitaldaemon.com>, Hasan Aljudy says...
> 
>>I didn't read/undertstand your entire post, but I think what you're trying to achieve here can already be achieved through polymorphism.
>>
>>I think you just need to redeisgn the classes a little bit.
>>
>>
> 
> I don't think that would (always) work. Consider the following:
> 
> interface IA
> {
> int get();
> }
> 
> interface IB
> {
> int get();
> }
> 
> class C : IA, IB
> {
> public int i;
> // illegal but ...
> int get() { return i+1; } // get for IA
> int get() { return i+2; } // get for IB
> }
> 
> void main()
> {
> auto obj = new C;
> IA a = obj;
> IB b = obj;
> 
> obj.i = 0;
> writef(a.get, \n);	// should print 1
> writef(b.get, \n);	// should print 2
> 
> obj.i = 2;
> writef(a.get, \n);	// should print 3
> writef(b.get, \n);	// should print 4
> 
> }
> 
> Both "a" and "b" are actually pointing to obj but calls to "get" using them are
> supposed to differ. Some types of this problem could be handled by deriving
> classes from C but not when the interfaces must actually be dealing with the
> same object.
> 
> Cases like this could really happen if someone needs to implement two interfaces
> from different libraries in the same class.
> 
> 

I know, I'm saying, you can do this using polymorphism, along with a redesign, invloving decoupling the get method from the C class.

    class C
    {
        protected int i;
    }

    abstract class CGetter
    {
        abstract int get( C c );
    }

    class CA : CGetter
    {
        int get( C c )
        {
            return c.i + 1;
        }
    }

    class CB : CGetter
    {
        int get( C c )
        {
            return c.i + 2;
        }
    }

    void main()
    {
        auto obj = new C;
        CA a = new CA;
        CB b = new CB;

        obj.i = 0;

        writefln(a.get(c));    // should print 1
        writefln(b.get(c));    // should print 2

        obj.i = 2;
        writefln(a.get(c));    // should print 3
        writefln(b.get(c));    // should print 4
    }



A bit more complicated (for this simple example), but you're doing the same thing: creating new entries in a vtable, to choose different functions at runtime.

April 15, 2006
Hasan Aljudy wrote:
> BCS wrote:
> 
>> In article <e1riem$3jd$1@digitaldaemon.com>, Hasan Aljudy says...
>>
>>> I didn't read/undertstand your entire post, but I think what you're trying to achieve here can already be achieved through polymorphism.
>>>
>>> I think you just need to redeisgn the classes a little bit.
>>>
>>>
>>
>> I don't think that would (always) work. Consider the following:
>>
>> interface IA
>> {
>> int get();
>> }
>>
>> interface IB
>> {
>> int get();
>> }
>>
>> class C : IA, IB
>> {
>> public int i;
>> // illegal but ...
>> int get() { return i+1; } // get for IA
>> int get() { return i+2; } // get for IB
>> }
>>
>> void main()
>> {
>> auto obj = new C;
>> IA a = obj;
>> IB b = obj;
>>
>> obj.i = 0;
>> writef(a.get, \n);    // should print 1
>> writef(b.get, \n);    // should print 2
>>
>> obj.i = 2;
>> writef(a.get, \n);    // should print 3
>> writef(b.get, \n);    // should print 4
>>
>> }
>>
>> Both "a" and "b" are actually pointing to obj but calls to "get" using them are
>> supposed to differ. Some types of this problem could be handled by deriving
>> classes from C but not when the interfaces must actually be dealing with the
>> same object.
>>
>> Cases like this could really happen if someone needs to implement two interfaces
>> from different libraries in the same class.
>>
>>
> 
> I know, I'm saying, you can do this using polymorphism, along with a redesign, invloving decoupling the get method from the C class.
> 
>     class C
>     {
>         protected int i;
>     }
> 
>     abstract class CGetter
>     {
>         abstract int get( C c );
>     }
> 
>     class CA : CGetter
>     {
>         int get( C c )
>         {
>             return c.i + 1;
>         }
>     }
> 
>     class CB : CGetter
>     {
>         int get( C c )
>         {
>             return c.i + 2;
>         }
>     }
> 
>     void main()
>     {
>         auto obj = new C;
>         CA a = new CA;
>         CB b = new CB;
> 
>         obj.i = 0;
> 
>         writefln(a.get(c));    // should print 1
>         writefln(b.get(c));    // should print 2
> 
>         obj.i = 2;
>         writefln(a.get(c));    // should print 3
>         writefln(b.get(c));    // should print 4
>     }
> 
> 
> 
> A bit more complicated (for this simple example), but you're doing the same thing: creating new entries in a vtable, to choose different functions at runtime.
> 

ouch, typo, replace a.get(c) with a.get(obj)

        obj.i = 0;

        writefln(a.get(obj));    // should print 1
        writefln(b.get(obj));    // should print 2

        obj.i = 2;
        writefln(a.get(obj));    // should print 3
        writefln(b.get(obj));    // should print 4
April 16, 2006
Two issues with this solution:

1> the solution does not use interfaces. The assumption I was working under is that I am given a pair of interfaces that both have a function with the same name and parameters but imply different actions. This is more or less trivial to get around, add a constructor to the CA and CB classes that stores the object to a member.

2> This solution breaks down in any but the most trial of cases, consider:

interface I {int get();}
interface J {int get();}

class C { int i; }

class CI : I
{
C c;
this(C cv) { c = cv; }
int get(){ return c.i + 1; }
}

class CJ : J
{
C c;
this(C cv) { c = cv; }
int get(){ return c.i + 2; }
}

// this works fine until we derive from C

class D
{
int get(){ return (i != 4)?54:42; }// must be override get in I
int get(){ return 4; }// must be override get in J
}

One solution is to make CI and CJ call C.getI and C.getJ from c, but that requires another level or two of indirection that can be avoided with a syntax that would allow us to dictate the mapping of class methods to interface methods



Basically, yes you can get around these issues without changing D but the solution is substantially inferior to what could be available with some small changes.


In article <e1rm6d$7u1$2@digitaldaemon.com>, Hasan Aljudy says...
>
>Hasan Aljudy wrote:
>> BCS wrote:
>>> In article <e1riem$3jd$1@digitaldaemon.com>, Hasan Aljudy says...
>>>
>>>> I didn't read/undertstand your entire post, but I think what you're trying to achieve here can already be achieved through polymorphism.
>>>>
>>>> I think you just need to redeisgn the classes a little bit.
>>>
>>> I don't think that would (always) work. Consider the following:
>>>
>>> interface IA
>>> {
>>> int get();
>>> }
>>>
>>> interface IB
>>> {
>>> int get();
>>> }
>>>
>>> class C : IA, IB
>>> {
>>> public int i;
>>> // illegal but ...
>>> int get() { return i+1; } // get for IA
>>> int get() { return i+2; } // get for IB
>>> }
>>>
>>> void main()
>>> {
>>> auto obj = new C;
>>> IA a = obj;
>>> IB b = obj;
>>>
>>> obj.i = 0;
>>> writef(a.get, \n);    // should print 1
>>> writef(b.get, \n);    // should print 2
>>>
>>> obj.i = 2;
>>> writef(a.get, \n);    // should print 3
>>> writef(b.get, \n);    // should print 4
>>>
>>> }
>>>
>>> Both "a" and "b" are actually pointing to obj but calls to "get" using
>>> them are
>>> supposed to differ. Some types of this problem could be handled by
>>> deriving
>>> classes from C but not when the interfaces must actually be dealing
>>> with the
>>> same object.
>>>
>>> Cases like this could really happen if someone needs to implement two
>>> interfaces
>>> from different libraries in the same class.
>> 
>> I know, I'm saying, you can do this using polymorphism, along with a redesign, invloving decoupling the get method from the C class.
>> 
>>     class C
>>     {
>>         protected int i;
>>     }
>> 
>>     abstract class CGetter
>>     {
>>         abstract int get( C c );
>>     }
>> 
>>     class CA : CGetter
>>     {
>>         int get( C c )
>>         {
>>             return c.i + 1;
>>         }
>>     }
>> 
>>     class CB : CGetter
>>     {
>>         int get( C c )
>>         {
>>             return c.i + 2;
>>         }
>>     }
>> 
>>     void main()
>>     {
>>         auto obj = new C;
>>         CA a = new CA;
>>         CB b = new CB;
>> 
>>         obj.i = 0;
>> 
>>         writefln(a.get(c));    // should print 1
>>         writefln(b.get(c));    // should print 2
>> 
>>         obj.i = 2;
>>         writefln(a.get(c));    // should print 3
>>         writefln(b.get(c));    // should print 4
>>     }
>> 
>> 
>> 
>> A bit more complicated (for this simple example), but you're doing the same thing: creating new entries in a vtable, to choose different functions at runtime.
>> 
>
>ouch, typo, replace a.get(c) with a.get(obj)
>
>         obj.i = 0;
>
>         writefln(a.get(obj));    // should print 1
>         writefln(b.get(obj));    // should print 2
>
>         obj.i = 2;
>         writefln(a.get(obj));    // should print 3
>         writefln(b.get(obj));    // should print 4


April 16, 2006
What you want is exactly what polymorphism is designed for. I really don't understand what's your problem.

BCS wrote:
> Two issues with this solution:
> 
> 1> the solution does not use interfaces. The assumption I was working under is
> that I am given a pair of interfaces that both have a function with the same
> name and parameters but imply different actions. This is more or less trivial to
> get around, add a constructor to the CA and CB classes that stores the object to
> a member.
> 
> 2> This solution breaks down in any but the most trial of cases, consider:
> 
> interface I {int get();}
> interface J {int get();}
> 
> class C { int i; }
> 
> class CI : I
> {
> C c;
> this(C cv) { c = cv; }
> int get(){ return c.i + 1; }
> }
> 
> class CJ : J
> {
> C c;
> this(C cv) { c = cv; }
> int get(){ return c.i + 2; }
> }
> 
> // this works fine until we derive from C
> 
> class D
> {
> int get(){ return (i != 4)?54:42; }// must be override get in I
> int get(){ return 4; }// must be override get in J
> }
> 
> One solution is to make CI and CJ call C.getI and C.getJ from c, but that
> requires another level or two of indirection that can be avoided with a syntax
> that would allow us to dictate the mapping of class methods to interface methods
> 
> 
> 
> Basically, yes you can get around these issues without changing D but the
> solution is substantially inferior to what could be available with some small
> changes.
> 
> 
> In article <e1rm6d$7u1$2@digitaldaemon.com>, Hasan Aljudy says...
> 
>>Hasan Aljudy wrote:
>>
>>>BCS wrote:
>>>
>>>>In article <e1riem$3jd$1@digitaldaemon.com>, Hasan Aljudy says...
>>>>
>>>>
>>>>>I didn't read/undertstand your entire post, but I think what you're trying to achieve here can already be achieved through polymorphism.
>>>>>
>>>>>I think you just need to redeisgn the classes a little bit.
>>>>
>>>>I don't think that would (always) work. Consider the following:
>>>>
>>>>interface IA
>>>>{
>>>>int get();
>>>>}
>>>>
>>>>interface IB
>>>>{
>>>>int get();
>>>>}
>>>>
>>>>class C : IA, IB
>>>>{
>>>>public int i;
>>>>// illegal but ...
>>>>int get() { return i+1; } // get for IA
>>>>int get() { return i+2; } // get for IB
>>>>}
>>>>
>>>>void main()
>>>>{
>>>>auto obj = new C;
>>>>IA a = obj;
>>>>IB b = obj;
>>>>
>>>>obj.i = 0;
>>>>writef(a.get, \n);    // should print 1
>>>>writef(b.get, \n);    // should print 2
>>>>
>>>>obj.i = 2;
>>>>writef(a.get, \n);    // should print 3
>>>>writef(b.get, \n);    // should print 4
>>>>
>>>>}
>>>>
>>>>Both "a" and "b" are actually pointing to obj but calls to "get" using them are
>>>>supposed to differ. Some types of this problem could be handled by deriving
>>>>classes from C but not when the interfaces must actually be dealing with the
>>>>same object.
>>>>
>>>>Cases like this could really happen if someone needs to implement two interfaces
>>>>from different libraries in the same class.
>>>
>>>I know, I'm saying, you can do this using polymorphism, along with a redesign, invloving decoupling the get method from the C class.
>>>
>>>    class C
>>>    {
>>>        protected int i;
>>>    }
>>>
>>>    abstract class CGetter
>>>    {
>>>        abstract int get( C c );
>>>    }
>>>
>>>    class CA : CGetter
>>>    {
>>>        int get( C c )
>>>        {
>>>            return c.i + 1;
>>>        }
>>>    }
>>>
>>>    class CB : CGetter
>>>    {
>>>        int get( C c )
>>>        {
>>>            return c.i + 2;
>>>        }
>>>    }
>>>
>>>    void main()
>>>    {
>>>        auto obj = new C;
>>>        CA a = new CA;
>>>        CB b = new CB;
>>>
>>>        obj.i = 0;
>>>
>>>        writefln(a.get(c));    // should print 1
>>>        writefln(b.get(c));    // should print 2
>>>
>>>        obj.i = 2;
>>>        writefln(a.get(c));    // should print 3
>>>        writefln(b.get(c));    // should print 4
>>>    }
>>>
>>>
>>>
>>>A bit more complicated (for this simple example), but you're doing the same thing: creating new entries in a vtable, to choose different functions at runtime.
>>>
>>
>>ouch, typo, replace a.get(c) with a.get(obj)
>>
>>        obj.i = 0;
>>
>>        writefln(a.get(obj));    // should print 1
>>        writefln(b.get(obj));    // should print 2
>>
>>        obj.i = 2;
>>        writefln(a.get(obj));    // should print 3
>>        writefln(b.get(obj));    // should print 4
> 
> 
> 
« First   ‹ Prev
1 2 3 4