digitalmars.D.learn - Differing implementations for a function in two interfaces
- Lionello Lunesu (68/68) Apr 15 2006 Hi,
- Chris Nicholson-Sauls (24/28) Apr 15 2006 ...
- BCS (27/39) Apr 15 2006 Its not to clean but the use of aliases could be a solution to this and ...
- Lionello Lunesu (14/47) Apr 17 2006 Even when calling, I'd pick the "IB.get" syntax:
- Ryan Steen (6/12) Apr 18 2006 This example seems somehow flawed.
- Ryan Steen (13/22) Apr 15 2006 I do not see the problem here because the opApply from the different int...
- Lionello Lunesu (19/44) Apr 16 2006 Brilliant!!! Why didn't I think of that.. Indeed, it works. BUT, I could...
- Ryan Steen (4/5) Apr 17 2006 Only if the formal parameter lists stay the same. Is it a good design no...
- Lionello Lunesu (23/32) Apr 17 2006 Nice idea!
- Ryan Steen (2/4) Apr 17 2006 Those casts are superfluous and dangerous.
- Lionello Lunesu (3/10) Apr 17 2006 You're right. I first typed the mail and included the casts for clarity,...
- Hasan Aljudy (4/91) Apr 15 2006 I didn't read/undertstand your entire post, but I think what you're
- BCS (35/38) Apr 15 2006 I don't think that would (always) work. Consider the following:
- Hasan Aljudy (40/94) Apr 15 2006 I know, I'm saying, you can do this using polymorphism, along with a
- Hasan Aljudy (8/120) Apr 15 2006 ouch, typo, replace a.get(c) with a.get(obj)
- BCS (35/150) Apr 15 2006 Two issues with this solution:
- Hasan Aljudy (3/178) Apr 15 2006 What you want is exactly what polymorphism is designed for. I really
- BCS (27/29) Apr 15 2006 I don't believe that D can solve the following problem. I can see severa...
- BCS (8/14) Apr 15 2006 [...]
- Hasan Aljudy (11/55) Apr 15 2006 I would dump these requirements, talk to the guy who set them, and try
- BCS (24/86) Apr 16 2006 say that the interfaces are part of closed source libs, as such the only...
- Derek Parnell (34/70) Apr 15 2006 I understood that an 'interface' was just a way of stating that the
- BCS (21/95) Apr 16 2006 Yes, mostly. However if I understand them correctly, an interface also d...
- Lionello Lunesu (24/24) Apr 16 2006 Consider this:
- Ryan Steen (3/5) Apr 17 2006 Yes. Such design is flawed: to implement two completely unrelated interf...
- Hasan Aljudy (3/13) Apr 17 2006 Yeah, if you implement completely unrelated interfaces in one class ..
- Lionello Lunesu (5/13) Apr 17 2006 I don't agree. The interfaces might be unrelated, but they can still
- Ryan Steen (6/8) Apr 17 2006 Yes, but what might cause the need to have the implementation in one cla...
- Lionello Lunesu (3/17) Apr 17 2006 Can't inherit from 2 classes, only interfaces ;)
- Ryan Steen (4/5) Apr 17 2006 Correct. But I do not remember a request, that one has to inheret vom cl...
- Chris Nicholson-Sauls (7/23) Apr 17 2006 Here you lose encapsulation, wherein you are basically having to create ...
- Ryan Steen (3/4) Apr 17 2006 Yes. But my suggestion does not work anyway, because CA and CB must reim...
- BCS (3/32) Apr 17 2006 yes but only because its already hidden in there by the compiler
- BCS (16/26) Apr 17 2006 // ABC inc.'s DB lib (closed source lib)
- Ryan Steen (8/11) Apr 17 2006 I do not understand this exercise. There are two closed source libs for ...
- BCS (10/21) Apr 17 2006 Make a database item class using the database provided interface that ca...
- Lionello Lunesu (8/11) Apr 16 2006 Your solution is pretty close to what I had in the first place. The
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 { #interface IB { #class C : IA, IB { 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: #class Command { #class Result { #class ResultRow { #class ResultField { 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 { #interface IResultRow { #class ResultField { #class Command : IResult, IResultRow { // handle wrapper Or is there a solution to this pattern I haven't thought of yet? All comments are appreciated :) L.
Apr 15 2006
Lionello Lunesu wrote:#class Command : IResult, IResultRow { // handle wrapper......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? Just thinking. -- Chris Nicholson-Sauls
Apr 15 2006
In article <e1qgma$1ngm$1 digitaldaemon.com>, Chris Nicholson-Sauls says...Lionello Lunesu wrote: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; } 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.#class Command : IResult, IResultRow { // handle wrapper......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?
Apr 15 2006
Chris Nicholson-Sauls wrote:Lionello Lunesu wrote:Even when calling, I'd pick the "IB.get" syntax: #class C : IA, IB { #void main() { But there's probably some syntax parsing problem I know nothing about. L.#class Command : IResult, IResultRow { // handle wrapper......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? Just thinking. -- Chris Nicholson-Sauls
Apr 17 2006
In article <e21vvd$1sv1$1 digitaldaemon.com>, Lionello Lunesu says...#void main() {This example seems somehow flawed. Interfaces are in the role of assuring access to some and denying access to some other public features of the implementation, don't they? But if one has full access to the implementation as above, then their denials are ineffective. Therefore this cannot be the usual case.
Apr 18 2006
In article <e1qem7$1lvs$1 digitaldaemon.com>, Lionello Lunesu says...#class Command : IResult, IResultRow { // handle wrapperI 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
Apr 15 2006
Ryan Steen wrote:In article <e1qem7$1lvs$1 digitaldaemon.com>, Lionello Lunesu says...Brilliant!!! Why didn't I think of that.. Indeed, it works. BUT, I could not provide the opIndex and opCall operators: #class Parameter {..} #class Command { #class ResultRow { So the problem in the original post still applies to opIndex and opCall. Thanks a lot for the suggestion ;) L.#class Command : IResult, IResultRow { // handle wrapperI 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
Apr 16 2006
In article <e1vbp8$1lcq$1 digitaldaemon.com>, Lionello Lunesu says...So the problem in the original post still applies to opIndex and opCall.Only if the formal parameter lists stay the same. Is it a good design not to have typedef'ed subtypes for fieldnames and parameternames, rowindex and columnindex?
Apr 17 2006
Ryan Steen wrote:In article <e1vbp8$1lcq$1 digitaldaemon.com>, Lionello Lunesu says...Nice idea! #typedef uint field_no; #typedef uint param_no; #interface IA { #interface IB { #class C : IA, IB { #void main() { Excellent, really... I think I'm in love... L.So the problem in the original post still applies to opIndex and opCall.Only if the formal parameter lists stay the same. Is it a good design not to have typedef'ed subtypes for fieldnames and parameternames, rowindex and columnindex?
Apr 17 2006
In article <e1vlef$21vv$1 digitaldaemon.com>, Lionello Lunesu says...Those casts are superfluous and dangerous.
Apr 17 2006
Ryan Steen wrote:In article <e1vlef$21vv$1 digitaldaemon.com>, Lionello Lunesu says...You're right. I first typed the mail and included the casts for clarity, and only later made a source file out of it.Those casts are superfluous and dangerous.
Apr 17 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 { #interface IB { #class C : IA, IB { 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: #class Command { #class Result { #class ResultRow { #class ResultField { 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 { #interface IResultRow { #class ResultField { #class Command : IResult, IResultRow { // handle wrapper Or is there a solution to this pattern I haven't thought of yet? All comments are appreciated :) L.
Apr 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.
Apr 15 2006
BCS wrote:In article <e1riem$3jd$1 digitaldaemon.com>, Hasan Aljudy says...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.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.
Apr 15 2006
Hasan Aljudy wrote:BCS wrote: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 4In article <e1riem$3jd$1 digitaldaemon.com>, Hasan Aljudy says...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.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.
Apr 15 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: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 4In article <e1riem$3jd$1 digitaldaemon.com>, Hasan Aljudy says...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.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.
Apr 15 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: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 4In article <e1riem$3jd$1 digitaldaemon.com>, Hasan Aljudy says...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.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.
Apr 15 2006
In article <e1s2sr$n4s$1 digitaldaemon.com>, Hasan Aljudy says...What you want is exactly what polymorphism is designed for. I really don't understand what's your problem.I don't believe that D can solve the following problem. I can see several way to get a _similar_ effect but all have substantial penalties involving code complexity, speed or maintainability/extensibility If you can use you suggested approach to solve this problem I would be pleased to see it. --------------- You are given this (you may not modify it) interface I {int get();} interface J {int get();} 1) You need to make a class C that implements both I and J that has different action for I.get and J.get. 2) Classes derived from C must be able to override the action of both I.get and Jget 3) Given an instance, c, of the class C, the following statements must work. I i = c; i.get // must call the appropriate I.get even if c is of a derived type. J j = c j.get // must call the appropriate J.get even if c is of a derived type. 4) Converting a C object to an I or J interface must not rely on the overloading of the cast operation (e.i. "I i = c;" must not call any methods) 5) Must be simply extendable to interfaces with lots of function (one more function in I must not require more than one function be defined to keep C up to date) I believe these requirements for a programming solution to be vary reasonable. If I were working in a programming shop and assigned a subordinate to the problem as defined through point 2, I would expect that 3-5 would be assumed.
Apr 15 2006
In article <e1s7gd$r15$1 digitaldaemon.com>, BCS says...In article <e1s2sr$n4s$1 digitaldaemon.com>, Hasan Aljudy says...[...] Oops: I forgot to state my position The problem I stated before is conceptually vary easy to solve: somehow, explicitly set the contents of the vtbls used by C when cast to I or J. The solution that you proposed, while workable, is a vary poor design. It is wasteful in runtime, program size, memory usage, code size and maintenance cost.What you want is exactly what polymorphism is designed for. I really don't understand what's your problem.I don't believe that D can solve the following problem.
Apr 15 2006
BCS wrote:In article <e1s2sr$n4s$1 digitaldaemon.com>, Hasan Aljudy says...I would dump these requirements, talk to the guy who set them, and try to figure out what problem he was trying to solve, then I'd make a better design.What you want is exactly what polymorphism is designed for. I really don't understand what's your problem.I don't believe that D can solve the following problem. I can see several way to get a _similar_ effect but all have substantial penalties involving code complexity, speed or maintainability/extensibility If you can use you suggested approach to solve this problem I would be pleased to see it. --------------- You are given this (you may not modify it) interface I {int get();} interface J {int get();} 1) You need to make a class C that implements both I and J that has different action for I.get and J.get. 2) Classes derived from C must be able to override the action of both I.get and Jget 3) Given an instance, c, of the class C, the following statements must work. I i = c; i.get // must call the appropriate I.get even if c is of a derived type. J j = c j.get // must call the appropriate J.get even if c is of a derived type. 4) Converting a C object to an I or J interface must not rely on the overloading of the cast operation (e.i. "I i = c;" must not call any methods) 5) Must be simply extendable to interfaces with lots of function (one more function in I must not require more than one function be defined to keep C up to date) I believe these requirements for a programming solution to be vary reasonable. If I were working in a programming shop and assigned a subordinate to the problem as defined through point 2, I would expect that 3-5 would be assumed.The problem I stated before is conceptually vary easy to solve: somehow, explicitly set the contents of the vtbls used by C when cast to I orJ. Thesolution that you proposed, while workable, is a vary poor design. It is wasteful in runtime, program size, memory usage, code size andmaintenance cost. It's not very easy, and I don't see how it improves performance. 1. It requires a substantial change to the grammar; namely, function names are not simply identifiers any more. 2. I don't see where's the performance gain; you're still using vtables. I don't even see how it's supposed to be a "better design".
Apr 15 2006
In article <e1s99b$sop$1 digitaldaemon.com>, Hasan Aljudy says...BCS wrote:say that the interfaces are part of closed source libs, as such the only part that is available for redesign is that part that is being designed by the hypothetical subordinate.In article <e1s2sr$n4s$1 digitaldaemon.com>, Hasan Aljudy says...I would dump these requirements, talk to the guy who set them, and try to figure out what problem he was trying to solve, then I'd make a better design.What you want is exactly what polymorphism is designed for. I really don't understand what's your problem.I don't believe that D can solve the following problem. I can see several way to get a _similar_ effect but all have substantial penalties involving code complexity, speed or maintainability/extensibility If you can use you suggested approach to solve this problem I would be pleased to see it. --------------- You are given this (you may not modify it) interface I {int get();} interface J {int get();} 1) You need to make a class C that implements both I and J that has different action for I.get and J.get. 2) Classes derived from C must be able to override the action of both I.get and Jget 3) Given an instance, c, of the class C, the following statements must work. I i = c; i.get // must call the appropriate I.get even if c is of a derived type. J j = c j.get // must call the appropriate J.get even if c is of a derived type. 4) Converting a C object to an I or J interface must not rely on the overloading of the cast operation (e.i. "I i = c;" must not call any methods) 5) Must be simply extendable to interfaces with lots of function (one more function in I must not require more than one function be defined to keep C up to date) I believe these requirements for a programming solution to be vary reasonable. If I were working in a programming shop and assigned a subordinate to the problem as defined through point 2, I would expect that 3-5 would be assumed.This is exactly what I am saying should be doneThe problem I stated before is conceptually vary easy to solve: somehow, explicitly set the contents of the vtbls used by C when cast to I or J. The solution that you proposed, while workable, is a vary poor design. It is wasteful in runtime, program size, memory usage, code size and maintenance cost.It's not very easy, and I don't see how it improves performance. 1. It requires a substantial change to the grammar;namely, function names are not simply identifiers any more.Not necessarily a syntax like the following wouldn't require any change to the function definition syntax. Also it would allow a function to implement an interface without having the same name as the function in the interface (useful if that name is already used by a inherited class). class C : I, J { int getI(){...} int getI(){...} alias getI I.get; alias getJ J.get; }2. I don't see where's the performance gain; you're still using vtables.Yes but only one vtable and only one level of function call. Alternate solutions require the use of otherwise unneeded object with methods that simply wrap other methods. I would consider that pure waste.I don't even see how it's supposed to be a "better design".I am considering this problem from the standpoint of the efficiency of the final product. I consider this objective to be of great importance, more so than the how easy it is to write the program (and to some degree the simplicity of the language). From this perspective, all available solutions to the problem are wistful. Some people take the opposite view, which supports different solutions.
Apr 16 2006
On Sun, 16 Apr 2006 11:43:41 +1000, BCS <BCS_member pathlink.com> wrote:In article <e1s2sr$n4s$1 digitaldaemon.com>, Hasan Aljudy says...I understood that an 'interface' was just a way of stating that the methods named in it must be implemented by any class that is derived from the interface. In other words, that the class must implement a method with the same name and parameter signature. So if two interfaces have the same method defined, then the class that is derived from both must define a method (one method) of the same name etc...What you want is exactly what polymorphism is designed for. I really don't understand what's your problem.I don't believe that D can solve the following problem. I can see several way to get a _similar_ effect but all have substantial penalties involving code complexity, speed or maintainability/extensibility If you can use you suggested approach to solve this problem I would be pleased to see it. --------------- You are given this (you may not modify it) interface I {int get();} interface J {int get();}1) You need to make a class C that implements both I and J that has different action for I.get and J.get.You can't do this in one class. I guess you can do ... class IC: I { int get(){ return 1; } } class JC: J { int get(){ return 2; } } class C { IC i; JC j; . . . } C c = new C; c.i.get; // must call the appropriate I.get even if c is of a derived type. c.j.get; // must call the appropriate J.get even if c is of a derived type.2) Classes derived from C must be able to override the action of both I.get and J.getBut there are no actions defined for these interface methods, just signatures. There is nothing to override.3) Given an instance, c, of the class C, the following statements must work. I i = c; i.get // must call the appropriate I.get even if c is of a derived type. J j = c j.get // must call the appropriate J.get even if c is of a derived type. 4) Converting a C object to an I or J interface must not rely on the overloading of the cast operation (e.i. "I i = c;" must not call any methods) 5) Must be simply extendable to interfaces with lots of function (one more function in I must not require more than one function be defined to keep C up to date)It seems that 'interface' in D means something different from what you mean by the term. -- Derek Parnell Melbourne, Australia
Apr 15 2006
In article <op.s72xewiy6b8z09 ginger.vic.bigpond.net.au>, Derek Parnell says...On Sun, 16 Apr 2006 11:43:41 +1000, BCS <BCS_member pathlink.com> wrote:Yes, mostly. However if I understand them correctly, an interface also defines a actual data structure that consist of a context pointer (the pointer to the object) and a separate vtbl pointer that points to a vtbl that is different from the vtbl of the implementing class. The point of this is that each interface has a layout for this vtbl that is independent of the layout of the classes vtbl. This has the effect that code that uses a interface only needs to known that layout and not anything about the class it is actually using.In article <e1s2sr$n4s$1 digitaldaemon.com>, Hasan Aljudy says...I understood that an 'interface' was just a way of stating that the methods named in it must be implemented by any class that is derived from the interface. In other words, that the class must implement a method with the same name and parameter signature. So if two interfaces have the same method defined, then the class that is derived from both must define a method (one method) of the same name etc...What you want is exactly what polymorphism is designed for. I really don't understand what's your problem.I don't believe that D can solve the following problem. I can see several way to get a _similar_ effect but all have substantial penalties involving code complexity, speed or maintainability/extensibility If you can use you suggested approach to solve this problem I would be pleased to see it. --------------- You are given this (you may not modify it) interface I {int get();} interface J {int get();}The point is that if E is derived from C, than the effect of casting a E object to type I and calling get can be defined in E class E : C { int get() { /* new functionality*/ ...} } E e = new E; I i = e; i.get; // calls the function in E1) You need to make a class C that implements both I and J that has different action for I.get and J.get.You can't do this in one class. I guess you can do ... class IC: I { int get(){ return 1; } } class JC: J { int get(){ return 2; } } class C { IC i; JC j; . . . } C c = new C; c.i.get; // must call the appropriate I.get even if c is of a derived type. c.j.get; // must call the appropriate J.get even if c is of a derived type.2) Classes derived from C must be able to override the action of both I.get and J.getBut there are no actions defined for these interface methods, just signatures. There is nothing to override.I may be totally wrong, but I think that interfaces are a bit more than what you are thinking of. The documentation I have found on them is kind of thin and doesn't do a good job of describing what they actually are doing behind the scenes. Most of this I have had to puzzle out my self.3) Given an instance, c, of the class C, the following statements must work. I i = c; i.get // must call the appropriate I.get even if c is of a derived type. J j = c j.get // must call the appropriate J.get even if c is of a derived type. 4) Converting a C object to an I or J interface must not rely on the overloading of the cast operation (e.i. "I i = c;" must not call any methods) 5) Must be simply extendable to interfaces with lots of function (one more function in I must not require more than one function be defined to keep C up to date)It seems that 'interface' in D means something different from what you mean by the term.-- Derek Parnell Melbourne, Australia
Apr 16 2006
Consider this: Two interfaces are part of different third party modules. One module wants you to provide an implementation for interface IA and a completely different module needs some interface IB. They are completely unrelated. No problem at all. Your application class can easily interface with both: class C : IA, IB { // implement all of IA's methods ... // implement all of IB's methods ... } And you provide cast(IA)this to module A and cast(IB)this to module B. No worries. After some time, a new version has come out for both the third party modules, each with some added functionality. However, all programmers being human (last time I checked) they're pretty bad at randomness and they both declared a method "int get()" in their interfaces. Now you're in trouble. There's no way you can provide one implementation for both "int get()"s, since they are completely unrelated. IA.get is used in a completely different context from IB.get. Now what? Redesign the whole app and make multiple classes? I wish there was another way. L.
Apr 16 2006
In article <e1vci0$1luu$1 digitaldaemon.com>, Lionello Lunesu says...They are completely unrelated. Now what? Redesign the whole app and make multiple classes?Yes. Such design is flawed: to implement two completely unrelated interfaces in one single class.
Apr 17 2006
Ryan Steen wrote:In article <e1vci0$1luu$1 digitaldaemon.com>, Lionello Lunesu says...Yeah, if you implement completely unrelated interfaces in one class .. you only have yourself to blame.They are completely unrelated. Now what? Redesign the whole app and make multiple classes?Yes. Such design is flawed: to implement two completely unrelated interfaces in one single class.
Apr 17 2006
Ryan Steen wrote:In article <e1vci0$1luu$1 digitaldaemon.com>, Lionello Lunesu says...I don't agree. The interfaces might be unrelated, but they can still both apply to the class needing them. IA might be an interface for the output/GUI and IB for the input. L.They are completely unrelated. Now what? Redesign the whole app and make multiple classes?Yes. Such design is flawed: to implement two completely unrelated interfaces in one single class.
Apr 17 2006
In article <e1vlnb$226i$1 digitaldaemon.com>, Lionello Lunesu says...IA might be an interface for the output/GUI and IB for the input.Yes, but what might cause the need to have the implementation in one class? And if there is really a need what hinders a virtual split of that implenting class? IA --> CA <-- C --> CB <-- IB where --> and <-- denote inheretance?
Apr 17 2006
Ryan Steen wrote:In article <e1vlnb$226i$1 digitaldaemon.com>, Lionello Lunesu says...Can't inherit from 2 classes, only interfaces ;) L.IA might be an interface for the output/GUI and IB for the input.Yes, but what might cause the need to have the implementation in one class? And if there is really a need what hinders a virtual split of that implenting class? IA --> CA <-- C --> CB <-- IB where --> and <-- denote inheretance?
Apr 17 2006
In article <e1vroh$2805$2 digitaldaemon.com>, Lionello Lunesu says...Can't inherit from 2 classes, only interfaces ;)Correct. But I do not remember a request, that one has to inheret vom class C splitted into CA and CB. The implementation is shielded by the interfaces, isn't it?
Apr 17 2006
Ryan Steen wrote:In article <e1vlnb$226i$1 digitaldaemon.com>, Lionello Lunesu says...Here you lose encapsulation, wherein you are basically having to create a C, then ask it for its CA and later for its CB, and the CA/CB classes (inner classes, maybe?) have to know their parent object and ask it for the real data and behaviors. Ew, ew, ew. (Although at least inner classes won't need the parent pointer, once we settle on some kind of 'parent' or 'outer' keyword.) -- Chris Nicholson-SaulsIA might be an interface for the output/GUI and IB for the input.Yes, but what might cause the need to have the implementation in one class? And if there is really a need what hinders a virtual split of that implenting class? IA --> CA <-- C --> CB <-- IB where --> and <-- denote inheretance?
Apr 17 2006
In article <e20j3q$6lu$1 digitaldaemon.com>, Chris Nicholson-Sauls says...Here you lose encapsulationYes. But my suggestion does not work anyway, because CA and CB must reimplement the interfaces. Sorry.
Apr 17 2006
Chris Nicholson-Sauls wrote:Ryan Steen wrote:I fully agree.In article <e1vlnb$226i$1 digitaldaemon.com>, Lionello Lunesu says...Here you lose encapsulation, wherein you are basically having to create a C, then ask it for its CA and later for its CB, and the CA/CB classes (inner classes, maybe?) have to know their parent object and ask it for the real data and behaviors. Ew, ew, ew.IA might be an interface for the output/GUI and IB for the input.Yes, but what might cause the need to have the implementation in one class? And if there is really a need what hinders a virtual split of that implenting class? IA --> CA <-- C --> CB <-- IB where --> and <-- denote inheretance?(Although at least inner classes won't need the parent pointer,yes but only because its already hidden in there by the compileronce we settle on some kind of 'parent' or 'outer' keyword.) -- Chris Nicholson-Sauls
Apr 17 2006
Ryan Steen wrote:In article <e1vci0$1luu$1 digitaldaemon.com>, Lionello Lunesu says...// ABC inc.'s DB lib (closed source lib) interface DatabaseItemInterface { ... int get(); // load the data from the DB into the object, return something ... } // XYZ corp.'s finance framework (closed source lib) interface PerchaseRequest { ... int get(); // return the PO number for this item ... } // now, implement a finance databaseThey are completely unrelated. Now what? Redesign the whole app and make multiple classes?Yes. Such design is flawed: to implement two completely unrelated interfaces in one single class.
Apr 17 2006
In article <e212nr$o5p$1 digitaldaemon.com>, BCS says...interface DatabaseItemInterface interface PerchaseRequest // now, implement a finance databaseI do not understand this exercise. There are two closed source libs for which I have to provide the implementation? If there are no more constraints, then it is possible to write classes which implement the two interfacec by wrapping the appropriate functions from the main application, the finance database. But I already said it elsewhere, D would be better off with some features for renaming or aliasing interface content as well as interfaces themselves.
Apr 17 2006
In article <e219lb$1193$1 digitaldaemon.com>, Ryan Steen says...In article <e212nr$o5p$1 digitaldaemon.com>, BCS says...Make a database item class using the database provided interface that can be used by the finance lib (e.i. implements the finance interface). The need for the interfaces comes from the need for library functions to handle the objects. Inside of the libs the "get" functions will be called using the interfaces.interface DatabaseItemInterface interface PerchaseRequest // now, implement a finance databaseI do not understand this exercise. There are two closed source libs for which I have to provide the implementation?If there are no more constraints, then it is possible to write classes which implement the two interfacec by wrapping the appropriate functions from the main application, the finance database.I'm not sure what you are saying?? Something like this (extra classes and objects) has bean suggested but it looks really messy to me.But I already said it elsewhere, D would be better off with some features for renaming or aliasing interface content as well as interfaces themselves.Yes, this is exactly what I am suggesting. I have already outlined my suggested syntax elsewhere.
Apr 17 2006
Hasan Aljudy wrote: <snip>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.Your solution is pretty close to what I had in the first place. The reason I didn't like it was because of all the "new"s. CA and CB don't contain any data, but must be new'ed nonetheless. Furthermore, in your code you have to keep passing the C class to each call on CA and CB: not a viable solution. L.
Apr 16 2006