www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interfaces allow member definitions?

reply "Frustrated" <c1514843 drdrb.com> writes:
I was, I think, able to call an interface's method. I had the
code like the following


interface A
{
      void foo();
}

class B : A { void foo() { writeln("Hey"); } }
class C : A { void foo() { writeln("You"); } }

yet, when I called a.foo(); I did not get any output. (A being of
type A)


Now, I was doing some weird stuff but either in the vtable for A,
there are empty functions that do nothing or I just happen to
call bogus memory that did not throw an exception.

The real question is, do interface methods actually support
function definitions?

Is there anything that stops us from actually doing

interface A
{
      void foo() { writeln("What up!!"); }
}

internally? I know member functions require a this but in this
case foo does not require this so it any this would work.

Basically, does the vtable contain storage for the interface's
members but blocks us from using them due to the issue with this?

If so, then shouldn't we be able to create functions in an
interface as long as they do not reference this? (basically
static functions that can be overriden as dynamic functions in
the class)

e.g.,

interface A
{
          // default behavior for foo and bar
          void foo() { writeln("asdasdfasdfasdf"); }
	void bar() { writeln("1234"); }

}

class B : A
{
	void foo() { writeln("help"); }
}

void main()
{
	A a = new B;
          a.foo(); // prints help
          a.bar(); // prints 1234
          B b = new B;
          b.foo(); // prints help
          b.bar(); // prints 1234
}


This would allow one to sort of add default behavior to an
interface(limited since no fields could be used but properties
help with it).

basically the vtable just needs an extra spot for the interface
methods and calls them with null or the object it contains for
this... which doesn't matter since this is never used in the body
of the function.
Jan 30 2014
parent reply "TheFlyingFiddle" <theflyingfiddle gmail.com> writes:
On Thursday, 30 January 2014 at 11:19:58 UTC, Frustrated wrote:
 I was, I think, able to call an interface's method. I had the
 code like the following


 interface A
 {
      void foo();
 }

 class B : A { void foo() { writeln("Hey"); } }
 class C : A { void foo() { writeln("You"); } }

 yet, when I called a.foo(); I did not get any output. (A being 
 of
 type A)


 Now, I was doing some weird stuff but either in the vtable for 
 A,
 there are empty functions that do nothing or I just happen to
 call bogus memory that did not throw an exception.

 The real question is, do interface methods actually support
 function definitions?

 Is there anything that stops us from actually doing

 interface A
 {
      void foo() { writeln("What up!!"); }
 }

 internally? I know member functions require a this but in this
 case foo does not require this so it any this would work.

 Basically, does the vtable contain storage for the interface's
 members but blocks us from using them due to the issue with 
 this?

 If so, then shouldn't we be able to create functions in an
 interface as long as they do not reference this? (basically
 static functions that can be overriden as dynamic functions in
 the class)

 e.g.,

 interface A
 {
          // default behavior for foo and bar
          void foo() { writeln("asdasdfasdfasdf"); }
 	void bar() { writeln("1234"); }

 }

 class B : A
 {
 	void foo() { writeln("help"); }
 }

 void main()
 {
 	A a = new B;
          a.foo(); // prints help
          a.bar(); // prints 1234
          B b = new B;
          b.foo(); // prints help
          b.bar(); // prints 1234
 }


 This would allow one to sort of add default behavior to an
 interface(limited since no fields could be used but properties
 help with it).

 basically the vtable just needs an extra spot for the interface
 methods and calls them with null or the object it contains for
 this... which doesn't matter since this is never used in the 
 body
 of the function.
You can already do this using the Non-virtual interface ideom interface Foo { final void bar() { writeln("Something"); } void baz() { writeln("Something Else"); } } Note the final keyword it is imortant here. This will make bar simply be a non-virutal method in Foo. If you want to provide some basic implementation but still forward to a base class you can do something like this. interface Foo2 { final void bar(uint i) { // Does some basic stuff here. bar_impl(i); } protected void bar_impl(uint i); } class A : Foo2 { protected void bar_impl(uint i) { //Do some specific stuff here. } } This pattern allows you to do some basic stuff in bar and more specialized stuff in bar_impl. It does require that you overload bar_impl though which may not be what you want.
Jan 30 2014
next sibling parent reply "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> writes:
Compiling with DMD 2.064, I am NOT able to get any function in 
interfaces accepted unless they are final. This means you cannot 
provide default behavior in the interface, at least not in the 
ways shown above.
Jan 30 2014
parent "TheFlyingFiddle" <theflyingfiddle gmail.com> writes:
On Thursday, 30 January 2014 at 13:43:49 UTC, Casper Færgemand 
wrote:
 Compiling with DMD 2.064, I am NOT able to get any function in 
 interfaces accepted unless they are final. This means you 
 cannot provide default behavior in the interface, at least not 
 in the ways shown above.
Yes the void baz() method is incorrect. The rest should be fine though.
Jan 30 2014
prev sibling parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 11:29:55 UTC, TheFlyingFiddle
wrote:
 On Thursday, 30 January 2014 at 11:19:58 UTC, Frustrated wrote:
 I was, I think, able to call an interface's method. I had the
 code like the following


 interface A
 {
     void foo();
 }

 class B : A { void foo() { writeln("Hey"); } }
 class C : A { void foo() { writeln("You"); } }

 yet, when I called a.foo(); I did not get any output. (A being 
 of
 type A)


 Now, I was doing some weird stuff but either in the vtable for 
 A,
 there are empty functions that do nothing or I just happen to
 call bogus memory that did not throw an exception.

 The real question is, do interface methods actually support
 function definitions?

 Is there anything that stops us from actually doing

 interface A
 {
     void foo() { writeln("What up!!"); }
 }

 internally? I know member functions require a this but in this
 case foo does not require this so it any this would work.

 Basically, does the vtable contain storage for the interface's
 members but blocks us from using them due to the issue with 
 this?

 If so, then shouldn't we be able to create functions in an
 interface as long as they do not reference this? (basically
 static functions that can be overriden as dynamic functions in
 the class)

 e.g.,

 interface A
 {
         // default behavior for foo and bar
         void foo() { writeln("asdasdfasdfasdf"); }
 	void bar() { writeln("1234"); }

 }

 class B : A
 {
 	void foo() { writeln("help"); }
 }

 void main()
 {
 	A a = new B;
         a.foo(); // prints help
         a.bar(); // prints 1234
         B b = new B;
         b.foo(); // prints help
         b.bar(); // prints 1234
 }


 This would allow one to sort of add default behavior to an
 interface(limited since no fields could be used but properties
 help with it).

 basically the vtable just needs an extra spot for the interface
 methods and calls them with null or the object it contains for
 this... which doesn't matter since this is never used in the 
 body
 of the function.
You can already do this using the Non-virtual interface ideom interface Foo { final void bar() { writeln("Something"); } void baz() { writeln("Something Else"); } } Note the final keyword it is imortant here. This will make bar simply be a non-virutal method in Foo. If you want to provide some basic implementation but still forward to a base class you can do something like this. interface Foo2 { final void bar(uint i) { // Does some basic stuff here. bar_impl(i); } protected void bar_impl(uint i); } class A : Foo2 { protected void bar_impl(uint i) { //Do some specific stuff here. } } This pattern allows you to do some basic stuff in bar and more specialized stuff in bar_impl. It does require that you overload bar_impl though which may not be what you want.
But this is not what I am talking about. Obviously one could use a multitude of ways to accomplish the same task but nothing is simple, direct, and elegant. Do you realize you have to define two functions in the interface? I'm not asking about a work around but if what I am talking about can actually be done(does the vtable support this or can made to support it?)
Jan 30 2014
next sibling parent reply "John Chapman" <johnch_atms hotmail.com> writes:
On Thursday, 30 January 2014 at 14:31:05 UTC, Frustrated wrote:
 I'm not asking about a work around but if what I am talking 
 about
 can actually be done(does the vtable support this or can made to
 support it?)
It would work if you changed the interface to an abstract class.
Jan 30 2014
parent "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 15:18:12 UTC, John Chapman wrote:
 On Thursday, 30 January 2014 at 14:31:05 UTC, Frustrated wrote:
 I'm not asking about a work around but if what I am talking 
 about
 can actually be done(does the vtable support this or can made 
 to
 support it?)
It would work if you changed the interface to an abstract class.
But then you break the whole usage of interfaces. (multiple inheritance issue)
Jan 30 2014
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 09:31:05 -0500, Frustrated <c1514843 drdrb.com> wrote:


 I'm not asking about a work around but if what I am talking about
 can actually be done(does the vtable support this or can made to
 support it?)
Yes. Interfaces have no concrete vtable. Only classes do. A concrete class can decide what the vtable has in it, and if you had a "default" implementation, the compiler could stick that in there. Note that the default implementation only can call other member functions within the interface or module-level functions, interfaces cannot access any derived data or members. Whether such a change would be accepted? No clue. -Steve
Jan 30 2014
parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 15:28:24 UTC, Steven
Schveighoffer wrote:
 On Thu, 30 Jan 2014 09:31:05 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:


 I'm not asking about a work around but if what I am talking 
 about
 can actually be done(does the vtable support this or can made 
 to
 support it?)
Yes. Interfaces have no concrete vtable. Only classes do. A concrete class can decide what the vtable has in it, and if you had a "default" implementation, the compiler could stick that in there. Note that the default implementation only can call other member functions within the interface or module-level functions, interfaces cannot access any derived data or members. Whether such a change would be accepted? No clue. -Steve
Basically I see no reason why the compiler can't treat the interface as a class and allow "default" methods. (it would have to allow multiple inheritance on that class though) All it would do is make it easy to provide a default implementation(more of a static implementation but allows it to be overriden, which makes it useful). For example, when creating a design you would no longer have to specifically create a corresponding class to use for the interface. You could just provide some default implementations of everything(throw errors, write stuff, etc...) I think it would be probably rather easy to do by extending the vtable to have one lower level, the interface methods, which, in fact, could use this(so you could have a this in them but only reference other members of the interface). Essentially what it boils down to is treating interfaces like classes that have no fields). To avoid the diamond problem simply always choose the method that is not from the interface(since it is "default"), which is done naturally with the vtable. Of course, maybe this just creates the diamond problem for interfaces: "which default implementation to use"... which I'm not sure if it's a problem?
Jan 30 2014
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated <c1514843 drdrb.com> wrote:


 Essentially what it boils down to is treating interfaces like
 classes that have no fields). To avoid the diamond problem simply
 always choose the method that is not from the interface(since it
 is "default"), which is done naturally with the vtable.
It's simpler than that. A function is a block of code. A vtable entry points to a block of code. Just point the vtable entry at the block of code that is the default implementation. -Steve
Jan 30 2014
next sibling parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
Schveighoffer wrote:
 On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:


 Essentially what it boils down to is treating interfaces like
 classes that have no fields). To avoid the diamond problem 
 simply
 always choose the method that is not from the interface(since 
 it
 is "default"), which is done naturally with the vtable.
It's simpler than that. A function is a block of code. A vtable entry points to a block of code. Just point the vtable entry at the block of code that is the default implementation. -Steve
Right, this was my original point and why I thought there was already entries for the interface in the vtable(since I seemed to have called some function that did nothing when it should have). It seems so simple and offers some benefit(would at the very least stop requiring one to implement a class every time they want test a design. When programming to interfaces and using some type of factory it makes even more sense. It then could also be used to test is something is implemented(possibly for versioning). e.g., interface A { void hasSomeFeature() { assert(0, "Not implemented yet"); } } Someone can come along and implement the feature and you(the interface) knows it's implemented if it doesn't assert, set a flag, or whatever. Are you 100% sure no default space is created for the vtable? (trying to reconcile why that case I mentioned worked. I'll try to throw an example up... may have just been coincidence I didn't get a segfault)
Jan 30 2014
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 12:30:04 -0500, Frustrated <c1514843 drdrb.com> wrote:

 On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
 Schveighoffer wrote:
 On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated <c1514843 drdrb.com>  
 wrote:


 Essentially what it boils down to is treating interfaces like
 classes that have no fields). To avoid the diamond problem simply
 always choose the method that is not from the interface(since it
 is "default"), which is done naturally with the vtable.
It's simpler than that. A function is a block of code. A vtable entry points to a block of code. Just point the vtable entry at the block of code that is the default implementation. -Steve
Right, this was my original point and why I thought there was already entries for the interface in the vtable(since I seemed to have called some function that did nothing when it should have).
I think your original example should not have happened. Either there was a bug in the runtime, compiler, or your memory :)
 It seems so simple and offers some benefit(would at the very
 least stop requiring one to implement a class every time they
 want test a design. When programming to interfaces and using some
 type of factory it makes even more sense.
This is a misunderstanding, you still need to declare a class, because an interface is not a concrete type. But if there are default implementations for all the interface functions, you don't need to implement any of them!
 It then could also be used to test is something is
 implemented(possibly for versioning).

 e.g.,

 interface A
 {
      void hasSomeFeature() { assert(0, "Not implemented yet"); }
 }

 Someone can come along and implement the feature and you(the
 interface) knows it's implemented if it doesn't assert, set a
 flag, or whatever.

 Are you 100% sure no default space is created for the vtable?
 (trying to reconcile why that case I mentioned worked. I'll try
 to throw an example up... may have just been coincidence I didn't
 get a segfault)
I didn't write the compiler, so I'm not 100%, but I'm 99% sure :) -Steve
Jan 30 2014
parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 17:38:26 UTC, Steven
Schveighoffer wrote:
 On Thu, 30 Jan 2014 12:30:04 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:

 On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
 Schveighoffer wrote:
 On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:


 Essentially what it boils down to is treating interfaces like
 classes that have no fields). To avoid the diamond problem 
 simply
 always choose the method that is not from the 
 interface(since it
 is "default"), which is done naturally with the vtable.
It's simpler than that. A function is a block of code. A vtable entry points to a block of code. Just point the vtable entry at the block of code that is the default implementation. -Steve
Right, this was my original point and why I thought there was already entries for the interface in the vtable(since I seemed to have called some function that did nothing when it should have).
I think your original example should not have happened. Either there was a bug in the runtime, compiler, or your memory :)
Well, as usual, it is almost surely user error. I can't reproduce it so we'll just go with that.
 It seems so simple and offers some benefit(would at the very
 least stop requiring one to implement a class every time they
 want test a design. When programming to interfaces and using 
 some
 type of factory it makes even more sense.
This is a misunderstanding, you still need to declare a class, because an interface is not a concrete type. But if there are default implementations for all the interface functions, you don't need to implement any of them!
No, the point is, if all methods are defined, there is no need to create the class. Why create an empty class to instantiate it when the compiler can do it for you and you can instantiate the interface? This is what I mean by treating the interface as a class because for all purposes it is. (an interface is just an abstract container but it doesn't have to be) Again, all this could be done by the compiler internally by creating a class to back an interface and add it to the vtable. Instantiating the interface just returns that class. Calling a member on the interface's object calls the member of that class, who's body is provided in the interface definition. I can do this now, the whole point is I don't like code duplication! ;) interface A { void foo() { writeln("me"); } void bar(); } class _A // created internally by compiler { void foo() { writeln("me"); } // added by compiler copied from A void bar() { assert(0, "error"); } // added by compiler } A a = new A; // reinterpreted by compiler as A a = new _A; a.foo(); // prints me a.bar(); // asserts e.g., all we would see is interface A { void foo() { writeln("me"); } void bar(); } which is much nicer on the eyes and about half the code. One may argue that this blurs the lines between a class an interface but it doesn't. It can still have multiple inheritance but easily provide a default way to deal with stuff. Remember, the whole point of interfaces was to solve diamond problem. They also now provide the "contract"... I'm just trying to get them to provide the "contract" with default behavior.
Jan 30 2014
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 13:06:30 -0500, Frustrated <c1514843 drdrb.com> wrote:

 On Thursday, 30 January 2014 at 17:38:26 UTC, Steven
 Schveighoffer wrote:
 This is a misunderstanding, you still need to declare a class, because  
 an interface is not a concrete type. But if there are default  
 implementations for all the interface functions, you don't need to  
 implement any of them!
No, the point is, if all methods are defined, there is no need to create the class. Why create an empty class to instantiate it when the compiler can do it for you and you can instantiate the interface? This is what I mean by treating the interface as a class because for all purposes it is. (an interface is just an abstract container but it doesn't have to be) Again, all this could be done by the compiler internally by creating a class to back an interface and add it to the vtable. Instantiating the interface just returns that class. Calling a member on the interface's object calls the member of that class, who's body is provided in the interface definition. I can do this now, the whole point is I don't like code duplication! ;) interface A { void foo() { writeln("me"); } void bar(); } class _A // created internally by compiler { void foo() { writeln("me"); } // added by compiler copied from A void bar() { assert(0, "error"); } // added by compiler }
-Steve
Jan 30 2014
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 13:16:21 -0500, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:


Sorry, black hole just does nothing. it's white hole you want: -Steve
Jan 30 2014
prev sibling parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
Schveighoffer wrote:
 On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:


 Essentially what it boils down to is treating interfaces like
 classes that have no fields). To avoid the diamond problem 
 simply
 always choose the method that is not from the interface(since 
 it
 is "default"), which is done naturally with the vtable.
It's simpler than that. A function is a block of code. A vtable entry points to a block of code. Just point the vtable entry at the block of code that is the default implementation. -Steve
But what if you want to provide some default behavior? We are not dealing with abstract classes here. Since there is currently no way to do what I am saying no "solution" will be adequate unless it fulfills the behavior. (again, it's not like we can't accomplish basically the same thing, the point is mainly about simplification) The question was about if there was any innate reason why this type of behavior couldn't be accomplish using the vtable. I'm assuming there is none and it could easily be done? (the compiler just has to reserve the space and setup the pointers to the functions?)
Jan 30 2014
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 14:58:42 -0500, Frustrated <c1514843 drdrb.com> wrote:

 On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
 Schveighoffer wrote:
 On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated <c1514843 drdrb.com>  
 wrote:


 Essentially what it boils down to is treating interfaces like
 classes that have no fields). To avoid the diamond problem simply
 always choose the method that is not from the interface(since it
 is "default"), which is done naturally with the vtable.
It's simpler than that. A function is a block of code. A vtable entry points to a block of code. Just point the vtable entry at the block of code that is the default implementation. -Steve
But what if you want to provide some default behavior? We are not dealing with abstract classes here. Since there is currently no way to do what I am saying no "solution" will be adequate unless it fulfills the behavior. (again, it's not like we can't accomplish basically the same thing, the point is mainly about simplification) The question was about if there was any innate reason why this type of behavior couldn't be accomplish using the vtable. I'm assuming there is none and it could easily be done? (the compiler just has to reserve the space and setup the pointers to the functions?)
The interface defines the vtable, the class contains a value for that vtable. If you imagine an interface vtable like this: interface A { void foo(); } => struct A_vtbl { void function() foo; } Note the default value is NULL. When you create a class that inherits, it's class info contains an A_vtbl: class B : A { void foo() {writeln("hi";} } => struct B_typeinfo { A_vtbl a_interface = {&B.foo}; } And when you call foo on an instance of A, it uses the vtable, knowing that the layout is A_vtbl. (this is simplistic, the real thing is more complex to explain, it's somewhere on the docs). What I'm saying is, if you give a default to the function foo, then our straw-man A_vtbl looks like this: struct A_vtbl { void function() foo = A.default_foo; } And when you create B_typeinfo, if you haven't defined foo, it just points at that default foo (of course, you have to fill in B.foo, and for that, you actually have to do a thunk to convert to the interface I think, but this is not hard). But it's important to note that A does not define an instance of A_vtbl, just the layout! You still need a concrete class to get a vtable instance to point at. -Steve
Jan 30 2014
parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 20:17:23 UTC, Steven
Schveighoffer wrote:
 On Thu, 30 Jan 2014 14:58:42 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:

 On Thursday, 30 January 2014 at 17:11:24 UTC, Steven
 Schveighoffer wrote:
 On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:


 Essentially what it boils down to is treating interfaces like
 classes that have no fields). To avoid the diamond problem 
 simply
 always choose the method that is not from the 
 interface(since it
 is "default"), which is done naturally with the vtable.
It's simpler than that. A function is a block of code. A vtable entry points to a block of code. Just point the vtable entry at the block of code that is the default implementation. -Steve
But what if you want to provide some default behavior? We are not dealing with abstract classes here. Since there is currently no way to do what I am saying no "solution" will be adequate unless it fulfills the behavior. (again, it's not like we can't accomplish basically the same thing, the point is mainly about simplification) The question was about if there was any innate reason why this type of behavior couldn't be accomplish using the vtable. I'm assuming there is none and it could easily be done? (the compiler just has to reserve the space and setup the pointers to the functions?)
The interface defines the vtable, the class contains a value for that vtable. If you imagine an interface vtable like this: interface A { void foo(); } => struct A_vtbl { void function() foo; } Note the default value is NULL. When you create a class that inherits, it's class info contains an A_vtbl: class B : A { void foo() {writeln("hi";} } => struct B_typeinfo { A_vtbl a_interface = {&B.foo}; } And when you call foo on an instance of A, it uses the vtable, knowing that the layout is A_vtbl. (this is simplistic, the real thing is more complex to explain, it's somewhere on the docs). What I'm saying is, if you give a default to the function foo, then our straw-man A_vtbl looks like this: struct A_vtbl { void function() foo = A.default_foo; } And when you create B_typeinfo, if you haven't defined foo, it just points at that default foo (of course, you have to fill in B.foo, and for that, you actually have to do a thunk to convert to the interface I think, but this is not hard). But it's important to note that A does not define an instance of A_vtbl, just the layout! You still need a concrete class to get a vtable instance to point at. -Steve
But what I think you are failing to realize is that regardless that foo is defined in an interface, since foo does not use this, it does not depend on the object, so it does not need an object(for all practical purposes it is a static function but of course must take an object as the first parameter so it is compatible as a member function). Also, regardless that it is an interface, doesn't mean it can't have a concrete vtable to work with. The fact is that a vtable is more complex because it has the ability to call functions defined in a base class. In this case a "base" interface. Just because something doesn't exist there now doesn't mean it can't exist. Answer me this class A { void foo() { } } class B : A { } B b = new B; b.foo(); are you telling me there are actually two foo functions? or does b actually call A's foo passing it the object b e.g., the call made is actually foo(b); If so, then what if A is an interface? (by interface, I am talking about one that has a vtable created for it's members) interface A { void foo() { } } class B : A { } B b = new B; b.foo(); Whats the difference? Absolutely nothing but your interpretation of what an interface is. This is all about semantics. If you want to think of an interface as some idealized abstract compile time object that doesn't exist at run time and has no vtable then so be it. But that doesn't mean it has to be and I'm just saying it is limiting. Obviously the difference between the two above is that the compiler does not allow multiple inheritance w.r.t, to classes, and does not allow fields in interfaces, etc... but these rules can still be enforced on a class THAT HAS A VTABLE. I think you still keep trying to fit the square peg in the round hole. I'm not talking about what the compiler does... we know the above code as I intend it does not work.
Jan 30 2014
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 15:57:06 -0500, Frustrated <c1514843 drdrb.com> wrote:

 On Thursday, 30 January 2014 at 20:17:23 UTC, Steven
 Schveighoffer wrote:
 But it's important to note that A does not define an instance of  
 A_vtbl, just the layout! You still need a concrete class to get a  
 vtable instance to point at.
But what I think you are failing to realize is that regardless that foo is defined in an interface, since foo does not use this, it does not depend on the object, so it does not need an object(for all practical purposes it is a static function but of course must take an object as the first parameter so it is compatible as a member function).
But what if it does need an object? interface A { void foo() { bar();} // need 'this' to call bar void bar(); }
 Also, regardless that it is an interface, doesn't mean it can't
 have a concrete vtable to work with.

 The fact is that a vtable is more complex because it has the
 ability to call functions defined in a base class. In this case a
 "base" interface.

 Just because something doesn't exist there now doesn't mean it
 can't exist.
Keep in mind that an interface vtable exists as part of an object. The compiler knows this, and performs thunks when necessary.
 Answer me this

 class A { void foo() { } }
 class B : A {  }

 B b = new B;
 b.foo();

 are you telling me there are actually two foo functions? or does
 b actually call A's foo passing it the object b e.g., the call
 made is actually foo(b);
There is one function, but two vtables, one for A, and one for B. Both point at the same function.
 If so, then what if A is an interface? (by interface, I am
 talking about one that has a vtable created for it's members)

 interface A { void foo() { } }
 class B : A {  }

 B b = new B;
 b.foo();

 Whats the difference? Absolutely nothing but your interpretation
 of what an interface is.
The difference is, now there is only one vtable, and one interface vtable inside B. A has no vtables. If you do this: A a = new B; a now points at the interface struct *inside B's object*. When you call a.foo, it does this: 1. It looks up in the interface vtable for A that's specific for B (accessed via the interface struct in the object itself) to get the function to call. 2. Included in the interface vtable struct is an offset to add so the 'this' pointer actually points at the object itself instead of the interface struct.
 This is all about semantics. If you want to think of an interface
 as some idealized abstract compile time object that doesn't exist
 at run time and has no vtable then so be it. But that doesn't
 mean it has to be and I'm just saying it is limiting.
An interface instance and an object instance are two VERY different things, and are handled differently by the compiler. -Steve
Jan 30 2014
next sibling parent reply "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 21:16:05 UTC, Steven
Schveighoffer wrote:
 On Thu, 30 Jan 2014 15:57:06 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:

 On Thursday, 30 January 2014 at 20:17:23 UTC, Steven
 Schveighoffer wrote:
 But it's important to note that A does not define an instance 
 of A_vtbl, just the layout! You still need a concrete class 
 to get a vtable instance to point at.
But what I think you are failing to realize is that regardless that foo is defined in an interface, since foo does not use this, it does not depend on the object, so it does not need an object(for all practical purposes it is a static function but of course must take an object as the first parameter so it is compatible as a member function).
But what if it does need an object? interface A { void foo() { bar();} // need 'this' to call bar void bar(); }
I've said many times that the functions could not use this. If you are going to go that far then why not allow interfaces to have fields? In this case they would not be any different from classes.
 Also, regardless that it is an interface, doesn't mean it can't
 have a concrete vtable to work with.

 The fact is that a vtable is more complex because it has the
 ability to call functions defined in a base class. In this 
 case a
 "base" interface.

 Just because something doesn't exist there now doesn't mean it
 can't exist.
Keep in mind that an interface vtable exists as part of an object. The compiler knows this, and performs thunks when necessary.
 Answer me this

 class A { void foo() { } }
 class B : A {  }

 B b = new B;
 b.foo();

 are you telling me there are actually two foo functions? or 
 does
 b actually call A's foo passing it the object b e.g., the call
 made is actually foo(b);
There is one function, but two vtables, one for A, and one for B. Both point at the same function.
Yes, and they could point to the function defined in the interface. When they call it, they would pass themselves as this. The methods in the interface do not use this, so it doesn't matter (they could potentially use it but it would require that it always be valid)
 If so, then what if A is an interface? (by interface, I am
 talking about one that has a vtable created for it's members)

 interface A { void foo() { } }
 class B : A {  }

 B b = new B;
 b.foo();

 Whats the difference? Absolutely nothing but your 
 interpretation
 of what an interface is.
The difference is, now there is only one vtable, and one interface vtable inside B. A has no vtables. If you do this: A a = new B; a now points at the interface struct *inside B's object*. When you call a.foo, it does this: 1. It looks up in the interface vtable for A that's specific for B (accessed via the interface struct in the object itself) to get the function to call. 2. Included in the interface vtable struct is an offset to add so the 'this' pointer actually points at the object itself instead of the interface struct.
Who says A doesn't have a vtable? That's something that you are forcing on it. You have to get off that if we are ever to make any headway.
 This is all about semantics. If you want to think of an 
 interface
 as some idealized abstract compile time object that doesn't 
 exist
 at run time and has no vtable then so be it. But that doesn't
 mean it has to be and I'm just saying it is limiting.
An interface instance and an object instance are two VERY different things, and are handled differently by the compiler. -Steve
Again, you have to get off of what has been defined. You have the mentality exactly the same as those that thought the earth was flat, imaginary numbers were nonsense/useless, man couldn't go to the moon. If you define your knowledge on what you already know what is the point? You just run around in circles.... nothing changes.... you'll just continue believing the earth is flat...
Jan 30 2014
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 16:23:55 -0500, Frustrated <c1514843 drdrb.com> wrote:

 Again, you have to get off of what has been defined. You have the
 mentality exactly the same as those that thought the earth was
 flat, imaginary numbers were nonsense/useless, man couldn't go to
 the moon.
OK, then. With that, I shall retire from this discussion :) -Steve
Jan 30 2014
parent "Frustrated" <c1514843 drdrb.com> writes:
On Thursday, 30 January 2014 at 21:42:39 UTC, Steven
Schveighoffer wrote:
 On Thu, 30 Jan 2014 16:23:55 -0500, Frustrated 
 <c1514843 drdrb.com> wrote:

 Again, you have to get off of what has been defined. You have 
 the
 mentality exactly the same as those that thought the earth was
 flat, imaginary numbers were nonsense/useless, man couldn't go 
 to
 the moon.
OK, then. With that, I shall retire from this discussion :) -Steve
It would be nice if you could understand what I'm getting at but it's like I keep telling you the earth and you don't believe me ;) Almost surely we are arguing about different things. Mine is more syntax substitution and yours is more implementation. In any case, it doesn't matter because it will never be implemented the way I think it could be so we are just wasting our time(or I'm wasting yours, how ever you want to see it ;)
Jan 30 2014
prev sibling parent "Frustrated" <c1514843 drdrb.com> writes:
Simple question.

What are the difference between an interface and a class?

I'm not talking about what the compiler does with them. I'm
talking about what they were created to do, how they came about
etc.

If you have to explain to someone what a class is and what an
interface is, then you diff that, what is your answer?

vtables should not show up in your explanation(they would if I
didn't mention it and it shows that you are stuck on the
implementation aspect and can't see the forest).
Jan 30 2014