www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Interface Return Types

reply teqDruid <me teqdruid.com> writes:
Why isn't this possible? It'd be nice (actually, nearly necessary for
what I'm doing)

interface I
{
	I a();
}

class B : I
{
	B a()
	{
		return new B();
	}
	
	this()
	{}
}

Also, the error message:
class B 1interface function I.a is not implemented
Would be more legible if it was "interface" not "linterface", but that's
(obviously) very minor.

John
Aug 16 2004
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 16 Aug 2004 03:45:15 -0400, teqDruid wrote:

 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)
 
 interface I
 {
 	I a();
 }
 
 class B : I
 {
 	B a()
 	{
 		return new B();
 	}
 	
 	this()
 	{}
 }
 
 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but that's
 (obviously) very minor.
 
 John
Will it suit your purposes if you change it to ... I guess what you trying to do with function 'a' is to return only those members implemented in class 'B' that derive from interface 'I'. Here is my test using an expanded class to highlight multiple interfaces... // -------------- <code> import std.stdio; interface I { I a(); } interface J { void c(); } class B : I, J { I a() { return new B(); } void c(){ writef("C\n"); } } void main() { I i; J j; B b; b = new B; b.c(); i = b.a(); // j = b.a(); // cannot implicitly convert I to J // i.c(); // no property 'c' for type 'I' // j.c(); // Access Violation } // -------------- </code> -- Derek Melbourne, Australia 16/Aug/04 6:15:40 PM
Aug 16 2004
parent reply teqDruid <me teqdruid.com> writes:
On Mon, 16 Aug 2004 18:25:54 +1000, Derek Parnell wrote:

 On Mon, 16 Aug 2004 03:45:15 -0400, teqDruid wrote:
 
 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)
 
 interface I
 {
 	I a();
 }
 
 class B : I
 {
 	B a()
 	{
 		return new B();
 	}
 	
 	this()
 	{}
 }
 
 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but that's
 (obviously) very minor.
 
 John
Will it suit your purposes if you change it to ...
No. It will not. I've got a class that not only implements an interface, but adds functionality. I want whoever is using the library to use the class' extra functionality if they know it's that class, or just use the generic interface. One problem is that a lot of my code in that class calls methods that the interface provides, and methods that it doesn't. I don't see a reason why you shouldn't be able to do this... Perhaps I'll re-post this under bugs, since it'll basically stop me dead in my tracks in a week or so (since I'll run out of other things to do) John
Aug 16 2004
next sibling parent reply Derek <derek psyc.ward> writes:
On Mon, 16 Aug 2004 14:25:13 -0400, teqDruid wrote:

 On Mon, 16 Aug 2004 18:25:54 +1000, Derek Parnell wrote:
 
 On Mon, 16 Aug 2004 03:45:15 -0400, teqDruid wrote:
 
 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)
 
 interface I
 {
 	I a();
 }
 
 class B : I
 {
 	B a()
 	{
 		return new B();
 	}
 	
 	this()
 	{}
 }
 
 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but that's
 (obviously) very minor.
 
 John
Will it suit your purposes if you change it to ...
No. It will not. I've got a class that not only implements an interface, but adds functionality. I want whoever is using the library to use the class' extra functionality if they know it's that class, or just use the generic interface. One problem is that a lot of my code in that class calls methods that the interface provides, and methods that it doesn't.
Ah, I understand. You want to describe an interface such that it has a member that returns an instance of any class that implements that interface.
 I don't see a reason why you shouldn't be able to do this...  Perhaps I'll
 re-post this under bugs, since it'll basically stop me dead in my tracks
 in a week or so (since I'll run out of other things to do)
Yep that seems like a reasonable idea. I can't think of anyway that D can do this yet. Obviously returning 'Object' is too broad. This code works, but maybe its too untidy for you... ---------------- import std.stdio; interface I { I a(); } class B : I { I a(){return new B();} this() {writef("B\n");} void C() { writef("C\n"); } } void main() { B b; B c; b = new B; c = cast(B)b.a(); // Explicit cast! c.C(); } ------------- -- Derek Melbourne, Australia
Aug 16 2004
parent Deja Augustine <Deja_member pathlink.com> writes:
In article <1iqrvs0lqsir0.evfkehx7osgz$.dlg 40tude.net>, Derek says...
On Mon, 16 Aug 2004 14:25:13 -0400, teqDruid wrote:

 On Mon, 16 Aug 2004 18:25:54 +1000, Derek Parnell wrote:
 
 On Mon, 16 Aug 2004 03:45:15 -0400, teqDruid wrote:
 
 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)
 
 interface I
 {
 	I a();
 }
 
 class B : I
 {
 	B a()
 	{
 		return new B();
 	}
 	
 	this()
 	{}
 }
 
 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but that's
 (obviously) very minor.
 
 John
Will it suit your purposes if you change it to ...
No. It will not. I've got a class that not only implements an interface, but adds functionality. I want whoever is using the library to use the class' extra functionality if they know it's that class, or just use the generic interface. One problem is that a lot of my code in that class calls methods that the interface provides, and methods that it doesn't.
Ah, I understand. You want to describe an interface such that it has a member that returns an instance of any class that implements that interface.
 I don't see a reason why you shouldn't be able to do this...  Perhaps I'll
 re-post this under bugs, since it'll basically stop me dead in my tracks
 in a week or so (since I'll run out of other things to do)
Yep that seems like a reasonable idea. I can't think of anyway that D can do this yet. Obviously returning 'Object' is too broad. This code works, but maybe its too untidy for you... ---------------- import std.stdio; interface I { I a(); } class B : I { I a(){return new B();} this() {writef("B\n");} void C() { writef("C\n"); } } void main() { B b; B c; b = new B; c = cast(B)b.a(); // Explicit cast! c.C(); } ------------- -- Derek Melbourne, Australia
Eheh... helps to refresh your browser to see that there are new posts to a topic before replying :) -Deja
Aug 17 2004
prev sibling parent Deja Augustine <Deja_member pathlink.com> writes:
In article <pan.2004.08.16.18.25.13.608059 teqdruid.com>, teqDruid says...
On Mon, 16 Aug 2004 18:25:54 +1000, Derek Parnell wrote:

 On Mon, 16 Aug 2004 03:45:15 -0400, teqDruid wrote:
 
 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)
 
 interface I
 {
 	I a();
 }
 
 class B : I
 {
 	B a()
 	{
 		return new B();
 	}
 	
 	this()
 	{}
 }
 
 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but that's
 (obviously) very minor.
 
 John
Will it suit your purposes if you change it to ...
No. It will not. I've got a class that not only implements an interface, but adds functionality. I want whoever is using the library to use the class' extra functionality if they know it's that class, or just use the generic interface. One problem is that a lot of my code in that class calls methods that the interface provides, and methods that it doesn't. I don't see a reason why you shouldn't be able to do this... Perhaps I'll re-post this under bugs, since it'll basically stop me dead in my tracks in a week or so (since I'll run out of other things to do) John
This may seem a daft question, but have you tried casting? -Deja
Aug 17 2004
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
Because B is not "covariant" with I, so an instance of B cannot masquerade
as an instance of I without a cast.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but that's
 (obviously) very minor.

 John
Aug 16 2004
parent reply teqDruid <me teqdruid.com> writes:
Please forgive the ignorance, but I don't understand.  B
implements I, so an instance of B can be used as the I type.

If B's method a()'s signature were modified to return type I, then I would
have to do the following:

B b = new B();
B myB = cast(B)b.a();

Whereas if the example worked as given the following would also work:
I i = new B();
I myI = i.a();
since B (obviously) implements I, so can be implicitly cast to it.
Unless there is some sort of compiler limitation preventing such.

Could someone explain using smaller words?

John

On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:

 Because B is not "covariant" with I, so an instance of B cannot masquerade
 as an instance of I without a cast.
 
 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but that's
 (obviously) very minor.

 John
Aug 16 2004
parent reply "Walter" <newshound digitalmars.com> writes:
B can be *converted* to the I type, but cannot be used *directly* as an I
type. The layouts of the vtbl[]s are different. Think of it like this: a
long can be used as if it was a short, by just ignoring the upper bits. But
a float cannot be used as a short, because the representations are
different. But a float can be converted to a short.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.17.06.57.18.155076 teqdruid.com...
 Please forgive the ignorance, but I don't understand.  B
 implements I, so an instance of B can be used as the I type.

 If B's method a()'s signature were modified to return type I, then I would
 have to do the following:

 B b = new B();
 B myB = cast(B)b.a();

 Whereas if the example worked as given the following would also work:
 I i = new B();
 I myI = i.a();
 since B (obviously) implements I, so can be implicitly cast to it.
 Unless there is some sort of compiler limitation preventing such.

 Could someone explain using smaller words?

 John

 On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:

 Because B is not "covariant" with I, so an instance of B cannot
masquerade
 as an instance of I without a cast.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but
that's
 (obviously) very minor.

 John
Aug 17 2004
parent reply teqDruid <me teqdruid.com> writes:
I believe I understand now. So in order for the example to work, there
would have to be a mechanism to convert B to I during an implicit cast,
yes?  If so, why is that mechanism not there?

Thanks for the explanation
John

On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:

 B can be *converted* to the I type, but cannot be used *directly* as an I
 type. The layouts of the vtbl[]s are different. Think of it like this: a
 long can be used as if it was a short, by just ignoring the upper bits. But
 a float cannot be used as a short, because the representations are
 different. But a float can be converted to a short.
 
 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.06.57.18.155076 teqdruid.com...
 Please forgive the ignorance, but I don't understand.  B
 implements I, so an instance of B can be used as the I type.

 If B's method a()'s signature were modified to return type I, then I would
 have to do the following:

 B b = new B();
 B myB = cast(B)b.a();

 Whereas if the example worked as given the following would also work:
 I i = new B();
 I myI = i.a();
 since B (obviously) implements I, so can be implicitly cast to it.
 Unless there is some sort of compiler limitation preventing such.

 Could someone explain using smaller words?

 John

 On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:

 Because B is not "covariant" with I, so an instance of B cannot
masquerade
 as an instance of I without a cast.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly necessary for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but
that's
 (obviously) very minor.

 John
Aug 17 2004
next sibling parent reply "Walter" <newshound digitalmars.com> writes:
The mechanism to cast from I to a B is there via explicit cast. It cannot be
done implicitly, however, since not all I's can be cast to B.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.17.20.08.09.459888 teqdruid.com...
 I believe I understand now. So in order for the example to work, there
 would have to be a mechanism to convert B to I during an implicit cast,
 yes?  If so, why is that mechanism not there?

 Thanks for the explanation
 John

 On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:

 B can be *converted* to the I type, but cannot be used *directly* as an
I
 type. The layouts of the vtbl[]s are different. Think of it like this: a
 long can be used as if it was a short, by just ignoring the upper bits.
But
 a float cannot be used as a short, because the representations are
 different. But a float can be converted to a short.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.06.57.18.155076 teqdruid.com...
 Please forgive the ignorance, but I don't understand.  B
 implements I, so an instance of B can be used as the I type.

 If B's method a()'s signature were modified to return type I, then I
would
 have to do the following:

 B b = new B();
 B myB = cast(B)b.a();

 Whereas if the example worked as given the following would also work:
 I i = new B();
 I myI = i.a();
 since B (obviously) implements I, so can be implicitly cast to it.
 Unless there is some sort of compiler limitation preventing such.

 Could someone explain using smaller words?

 John

 On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:

 Because B is not "covariant" with I, so an instance of B cannot
masquerade
 as an instance of I without a cast.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly necessary
for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but
that's
 (obviously) very minor.

 John
Aug 17 2004
parent reply teqDruid <me teqdruid.com> writes:
I realize that... but I'm talking about converting from B to I, since the
vtbl[]s need to be converted.  B is always an I, so it works...
semantically at least.  If the vtbl[]s were converted during an implicit
cast, one would be able to override a method and return a sub-type of the
type in the original method, as I am trying to do in my example, correct?

John

On Tue, 17 Aug 2004 13:44:51 -0700, Walter wrote:

 The mechanism to cast from I to a B is there via explicit cast. It cannot be
 done implicitly, however, since not all I's can be cast to B.
 
 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.20.08.09.459888 teqdruid.com...
 I believe I understand now. So in order for the example to work, there
 would have to be a mechanism to convert B to I during an implicit cast,
 yes?  If so, why is that mechanism not there?

 Thanks for the explanation
 John

 On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:

 B can be *converted* to the I type, but cannot be used *directly* as an
I
 type. The layouts of the vtbl[]s are different. Think of it like this: a
 long can be used as if it was a short, by just ignoring the upper bits.
But
 a float cannot be used as a short, because the representations are
 different. But a float can be converted to a short.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.06.57.18.155076 teqdruid.com...
 Please forgive the ignorance, but I don't understand.  B
 implements I, so an instance of B can be used as the I type.

 If B's method a()'s signature were modified to return type I, then I
would
 have to do the following:

 B b = new B();
 B myB = cast(B)b.a();

 Whereas if the example worked as given the following would also work:
 I i = new B();
 I myI = i.a();
 since B (obviously) implements I, so can be implicitly cast to it.
 Unless there is some sort of compiler limitation preventing such.

 Could someone explain using smaller words?

 John

 On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:

 Because B is not "covariant" with I, so an instance of B cannot
masquerade
 as an instance of I without a cast.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly necessary
for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but
that's
 (obviously) very minor.

 John
Aug 17 2004
parent reply "Walter" <newshound digitalmars.com> writes:
But while B is always an I, an I is not always a B. Hence your base class,
which only knows about I, cannot implicitly cast it to B. All you need to do
is put an explicit cast to I in B.a().

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.17.21.48.12.427296 teqdruid.com...
 I realize that... but I'm talking about converting from B to I, since the
 vtbl[]s need to be converted.  B is always an I, so it works...
 semantically at least.  If the vtbl[]s were converted during an implicit
 cast, one would be able to override a method and return a sub-type of the
 type in the original method, as I am trying to do in my example, correct?

 John

 On Tue, 17 Aug 2004 13:44:51 -0700, Walter wrote:

 The mechanism to cast from I to a B is there via explicit cast. It
cannot be
 done implicitly, however, since not all I's can be cast to B.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.20.08.09.459888 teqdruid.com...
 I believe I understand now. So in order for the example to work, there
 would have to be a mechanism to convert B to I during an implicit cast,
 yes?  If so, why is that mechanism not there?

 Thanks for the explanation
 John

 On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:

 B can be *converted* to the I type, but cannot be used *directly* as
an
 I
 type. The layouts of the vtbl[]s are different. Think of it like
this: a
 long can be used as if it was a short, by just ignoring the upper
bits.
 But
 a float cannot be used as a short, because the representations are
 different. But a float can be converted to a short.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.06.57.18.155076 teqdruid.com...
 Please forgive the ignorance, but I don't understand.  B
 implements I, so an instance of B can be used as the I type.

 If B's method a()'s signature were modified to return type I, then I
would
 have to do the following:

 B b = new B();
 B myB = cast(B)b.a();

 Whereas if the example worked as given the following would also
work:
 I i = new B();
 I myI = i.a();
 since B (obviously) implements I, so can be implicitly cast to it.
 Unless there is some sort of compiler limitation preventing such.

 Could someone explain using smaller words?

 John

 On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:

 Because B is not "covariant" with I, so an instance of B cannot
masquerade
 as an instance of I without a cast.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly necessary
for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but
that's
 (obviously) very minor.

 John
Aug 17 2004
parent reply teqDruid <me teqdruid.com> writes:
I just don't understand when an I ever has to be implicitly converted to a
B.

interface I
{
	I a();
}

class B : I
{
	B a()
	{
		return new B();
	}
	
	this()
	{}
}

When someone wants to use a B, they can:
B b = new B();
B myNewB = b.a();
However, when someone wants to reference a B as an I, a conversion of the
vtbl[]s is required, as you tell me, so upon the following implicit cast:
I i = myNewB;
the B's vtbl[]s are converted to make it compatible with the I type. In
addition, any calls to the a() method:
I myNewI = i.a();
would have to invoke the the conversion.  The virtual table would just
have to be modified to call some sort of wrapper function, the way I see
it, although since I'm not familiar with compiler design or
implementation I'm not sure.  Is this not possible (or not practical for
some reason)?

I'm not trying to be belligerent, just trying to understand something I
clearly don't grasp very well.

John

On Tue, 17 Aug 2004 14:55:58 -0700, Walter wrote:

 But while B is always an I, an I is not always a B. Hence your base class,
 which only knows about I, cannot implicitly cast it to B. All you need to do
 is put an explicit cast to I in B.a().
 
 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.21.48.12.427296 teqdruid.com...
 I realize that... but I'm talking about converting from B to I, since the
 vtbl[]s need to be converted.  B is always an I, so it works...
 semantically at least.  If the vtbl[]s were converted during an implicit
 cast, one would be able to override a method and return a sub-type of the
 type in the original method, as I am trying to do in my example, correct?

 John

 On Tue, 17 Aug 2004 13:44:51 -0700, Walter wrote:

 The mechanism to cast from I to a B is there via explicit cast. It
cannot be
 done implicitly, however, since not all I's can be cast to B.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.20.08.09.459888 teqdruid.com...
 I believe I understand now. So in order for the example to work, there
 would have to be a mechanism to convert B to I during an implicit cast,
 yes?  If so, why is that mechanism not there?

 Thanks for the explanation
 John

 On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:

 B can be *converted* to the I type, but cannot be used *directly* as
an
 I
 type. The layouts of the vtbl[]s are different. Think of it like
this: a
 long can be used as if it was a short, by just ignoring the upper
bits.
 But
 a float cannot be used as a short, because the representations are
 different. But a float can be converted to a short.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.06.57.18.155076 teqdruid.com...
 Please forgive the ignorance, but I don't understand.  B
 implements I, so an instance of B can be used as the I type.

 If B's method a()'s signature were modified to return type I, then I
would
 have to do the following:

 B b = new B();
 B myB = cast(B)b.a();

 Whereas if the example worked as given the following would also
work:
 I i = new B();
 I myI = i.a();
 since B (obviously) implements I, so can be implicitly cast to it.
 Unless there is some sort of compiler limitation preventing such.

 Could someone explain using smaller words?

 John

 On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:

 Because B is not "covariant" with I, so an instance of B cannot
masquerade
 as an instance of I without a cast.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly necessary
for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface", but
that's
 (obviously) very minor.

 John
Aug 18 2004
parent "Walter" <newshound digitalmars.com> writes:
Consider the following code added to your project:

void bar()
{
    B b = new B();
    foo(b);
}

I foo(I i)
{
     return i.a();
}

The call to i.a() is calling B.a(), which returns a B. But foo() knows
nothing at all about B, it has never heard of B. It doesn't even know that
it received a B rather than an I. There's just no way it can somehow
determine that it has a B that needs converting to an I. Therefore, it is
B.a() that needs to do the conversion to I.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.18.07.31.02.236327 teqdruid.com...
 I just don't understand when an I ever has to be implicitly converted to a
 B.

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 When someone wants to use a B, they can:
 B b = new B();
 B myNewB = b.a();
 However, when someone wants to reference a B as an I, a conversion of the
 vtbl[]s is required, as you tell me, so upon the following implicit cast:
 I i = myNewB;
 the B's vtbl[]s are converted to make it compatible with the I type. In
 addition, any calls to the a() method:
 I myNewI = i.a();
 would have to invoke the the conversion.  The virtual table would just
 have to be modified to call some sort of wrapper function, the way I see
 it, although since I'm not familiar with compiler design or
 implementation I'm not sure.  Is this not possible (or not practical for
 some reason)?

 I'm not trying to be belligerent, just trying to understand something I
 clearly don't grasp very well.

 John

 On Tue, 17 Aug 2004 14:55:58 -0700, Walter wrote:

 But while B is always an I, an I is not always a B. Hence your base
class,
 which only knows about I, cannot implicitly cast it to B. All you need
to do
 is put an explicit cast to I in B.a().

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.21.48.12.427296 teqdruid.com...
 I realize that... but I'm talking about converting from B to I, since
the
 vtbl[]s need to be converted.  B is always an I, so it works...
 semantically at least.  If the vtbl[]s were converted during an
implicit
 cast, one would be able to override a method and return a sub-type of
the
 type in the original method, as I am trying to do in my example,
correct?
 John

 On Tue, 17 Aug 2004 13:44:51 -0700, Walter wrote:

 The mechanism to cast from I to a B is there via explicit cast. It
cannot be
 done implicitly, however, since not all I's can be cast to B.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.20.08.09.459888 teqdruid.com...
 I believe I understand now. So in order for the example to work,
there
 would have to be a mechanism to convert B to I during an implicit
cast,
 yes?  If so, why is that mechanism not there?

 Thanks for the explanation
 John

 On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:

 B can be *converted* to the I type, but cannot be used *directly*
as
 an
 I
 type. The layouts of the vtbl[]s are different. Think of it like
this: a
 long can be used as if it was a short, by just ignoring the upper
bits.
 But
 a float cannot be used as a short, because the representations are
 different. But a float can be converted to a short.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.17.06.57.18.155076 teqdruid.com...
 Please forgive the ignorance, but I don't understand.  B
 implements I, so an instance of B can be used as the I type.

 If B's method a()'s signature were modified to return type I,
then I
 would
 have to do the following:

 B b = new B();
 B myB = cast(B)b.a();

 Whereas if the example worked as given the following would also
work:
 I i = new B();
 I myI = i.a();
 since B (obviously) implements I, so can be implicitly cast to
it.
 Unless there is some sort of compiler limitation preventing such.

 Could someone explain using smaller words?

 John

 On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:

 Because B is not "covariant" with I, so an instance of B cannot
masquerade
 as an instance of I without a cast.

 "teqDruid" <me teqdruid.com> wrote in message
 news:pan.2004.08.16.07.45.15.79903 teqdruid.com...
 Why isn't this possible? It'd be nice (actually, nearly
necessary
 for
 what I'm doing)

 interface I
 {
 I a();
 }

 class B : I
 {
 B a()
 {
 return new B();
 }

 this()
 {}
 }

 Also, the error message:
 class B 1interface function I.a is not implemented
 Would be more legible if it was "interface" not "linterface",
but
 that's
 (obviously) very minor.

 John
Aug 19 2004
prev sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
One solution to your problem would be this implementation:

class B : I [
   B a_asB() {
     return new B();
   }
   I a() { return a_asB(); }
}

This would mean that you implement the correct I interface, but 
functions which know about your class can get access to B directly 
without having to cast it back.



Even nicer would be if you could do this:
WARNING: THIS CODE DOESN'T WORK:

class B : I {
   B a() {
     return new B();
   }
   I I.a() {
     return a();
   }
}



Walter, what are your thoughts on the above syntax as a feature for 2.0?

teqDruid wrote:
 I believe I understand now. So in order for the example to work, there
 would have to be a mechanism to convert B to I during an implicit cast,
 yes?  If so, why is that mechanism not there?
 
 Thanks for the explanation
 John
 
 On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:
 
 
B can be *converted* to the I type, but cannot be used *directly* as an I
type. The layouts of the vtbl[]s are different. Think of it like this: a
long can be used as if it was a short, by just ignoring the upper bits. But
a float cannot be used as a short, because the representations are
different. But a float can be converted to a short.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.17.06.57.18.155076 teqdruid.com...

Please forgive the ignorance, but I don't understand.  B
implements I, so an instance of B can be used as the I type.

If B's method a()'s signature were modified to return type I, then I would
have to do the following:

B b = new B();
B myB = cast(B)b.a();

Whereas if the example worked as given the following would also work:
I i = new B();
I myI = i.a();
since B (obviously) implements I, so can be implicitly cast to it.
Unless there is some sort of compiler limitation preventing such.

Could someone explain using smaller words?

John

On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:


Because B is not "covariant" with I, so an instance of B cannot
masquerade
as an instance of I without a cast.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.16.07.45.15.79903 teqdruid.com...

Why isn't this possible? It'd be nice (actually, nearly necessary for
what I'm doing)

interface I
{
I a();
}

class B : I
{
B a()
{
return new B();
}

this()
{}
}
Aug 17 2004
parent reply teqDruid <me teqdruid.com> writes:
Semantically, my example works.  If the compiler is going to support it,
there's no reason for a difference syntax.

There are ways for me to do what I'm trying to do, such as your example,
and casting, but both methods are... (and I don't believe there's any
other way to say this) yuckie.

On Tue, 17 Aug 2004 15:01:54 -0700, Russ Lewis wrote:

 One solution to your problem would be this implementation:
 
 class B : I [
    B a_asB() {
      return new B();
    }
    I a() { return a_asB(); }
 }
 
 This would mean that you implement the correct I interface, but 
 functions which know about your class can get access to B directly 
 without having to cast it back.
 
 
 
 Even nicer would be if you could do this:
 WARNING: THIS CODE DOESN'T WORK:
 
 class B : I {
    B a() {
      return new B();
    }
    I I.a() {
      return a();
    }
 }
 
 
 
 Walter, what are your thoughts on the above syntax as a feature for 2.0?
 
 teqDruid wrote:
 I believe I understand now. So in order for the example to work, there
 would have to be a mechanism to convert B to I during an implicit cast,
 yes?  If so, why is that mechanism not there?
 
 Thanks for the explanation
 John
 
 On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:
 
 
B can be *converted* to the I type, but cannot be used *directly* as an I
type. The layouts of the vtbl[]s are different. Think of it like this: a
long can be used as if it was a short, by just ignoring the upper bits. But
a float cannot be used as a short, because the representations are
different. But a float can be converted to a short.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.17.06.57.18.155076 teqdruid.com...

Please forgive the ignorance, but I don't understand.  B
implements I, so an instance of B can be used as the I type.

If B's method a()'s signature were modified to return type I, then I would
have to do the following:

B b = new B();
B myB = cast(B)b.a();

Whereas if the example worked as given the following would also work:
I i = new B();
I myI = i.a();
since B (obviously) implements I, so can be implicitly cast to it.
Unless there is some sort of compiler limitation preventing such.

Could someone explain using smaller words?

John

On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:


Because B is not "covariant" with I, so an instance of B cannot
masquerade
as an instance of I without a cast.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.16.07.45.15.79903 teqdruid.com...

Why isn't this possible? It'd be nice (actually, nearly necessary for
what I'm doing)

interface I
{
I a();
}

class B : I
{
B a()
{
return new B();
}

this()
{}
}
Aug 17 2004
next sibling parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
I hear you.  Ideally, the compiler would implement the "I.a()" 
definition for you.

teqDruid wrote:
 Semantically, my example works.  If the compiler is going to support it,
 there's no reason for a difference syntax.
 
 There are ways for me to do what I'm trying to do, such as your example,
 and casting, but both methods are... (and I don't believe there's any
 other way to say this) yuckie.
 
 On Tue, 17 Aug 2004 15:01:54 -0700, Russ Lewis wrote:
 
 
One solution to your problem would be this implementation:

class B : I [
   B a_asB() {
     return new B();
   }
   I a() { return a_asB(); }
}

This would mean that you implement the correct I interface, but 
functions which know about your class can get access to B directly 
without having to cast it back.



Even nicer would be if you could do this:
WARNING: THIS CODE DOESN'T WORK:

class B : I {
   B a() {
     return new B();
   }
   I I.a() {
     return a();
   }
}



Walter, what are your thoughts on the above syntax as a feature for 2.0?

teqDruid wrote:

I believe I understand now. So in order for the example to work, there
would have to be a mechanism to convert B to I during an implicit cast,
yes?  If so, why is that mechanism not there?

Thanks for the explanation
John

On Tue, 17 Aug 2004 00:10:56 -0700, Walter wrote:



B can be *converted* to the I type, but cannot be used *directly* as an I
type. The layouts of the vtbl[]s are different. Think of it like this: a
long can be used as if it was a short, by just ignoring the upper bits. But
a float cannot be used as a short, because the representations are
different. But a float can be converted to a short.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.17.06.57.18.155076 teqdruid.com...


Please forgive the ignorance, but I don't understand.  B
implements I, so an instance of B can be used as the I type.

If B's method a()'s signature were modified to return type I, then I would
have to do the following:

B b = new B();
B myB = cast(B)b.a();

Whereas if the example worked as given the following would also work:
I i = new B();
I myI = i.a();
since B (obviously) implements I, so can be implicitly cast to it.
Unless there is some sort of compiler limitation preventing such.

Could someone explain using smaller words?

John

On Mon, 16 Aug 2004 12:20:38 -0700, Walter wrote:



Because B is not "covariant" with I, so an instance of B cannot
masquerade
as an instance of I without a cast.

"teqDruid" <me teqdruid.com> wrote in message
news:pan.2004.08.16.07.45.15.79903 teqdruid.com...


Why isn't this possible? It'd be nice (actually, nearly necessary for
what I'm doing)

interface I
{
I a();
}

class B : I
{
B a()
{
return new B();
}

this()
{}
}
Aug 17 2004
prev sibling parent reply Matthias Becker <Matthias_member pathlink.com> writes:
Semantically, my example works.  If the compiler is going to support it,
there's no reason for a difference syntax.
It worcs semantically, correct, but it doesn't work techincally. It can't I and B aren't covariant!!! It's the way intefaces work, why it can't be done. If you have a base and a derived class they are covariant. There layout is the same. No conversation has to be performed. But class implementing interfaces aren't covariant to these intefaces. An implicit cast has to be perforemd. While you normaly can't see this, it is still there. class Foo { Foo m () {return new Foo();} } class Bar { Bar m () {return new Bar();} } Bar bar = new Bar(); Foo baz = bar.m(); // no technical conversation -- Matthias Becker
Aug 20 2004
parent reply Agent Smith <Agent_member pathlink.com> writes:
In article <cg4n3m$71g$1 digitaldaemon.com>, Matthias Becker says...

I and B aren't covariant!!!
What does "covariant" mean? Does "covariant" have anything to do with "invariant"? ^^ ^^ The prefix "co-" (as in "co-worker", "co-operation") implies symmetry. That is, I would expect that A is covariant with B if and only if B is covariant with A. Would that be a reasonable assumption?
Aug 20 2004
parent "Walter" <newshound digitalmars.com> writes:
"Agent Smith" <Agent_member pathlink.com> wrote in message
news:cg4o6e$7gg$1 digitaldaemon.com...
 In article <cg4n3m$71g$1 digitaldaemon.com>, Matthias Becker says...

I and B aren't covariant!!!
What does "covariant" mean? Does "covariant" have anything to do with "invariant"? ^^ ^^ The prefix "co-" (as in "co-worker", "co-operation") implies symmetry.
That is,
 I would expect that A is covariant with B if and only if B is covariant
with A.
 Would that be a reasonable assumption?
No. If "A" is a subset of "B", that doesn't imply that "B" is a subset of "A".
Aug 21 2004