digitalmars.D.learn - Interfaces allow member definitions?
- Frustrated (55/55) Jan 30 2014 I was, I think, able to call an interface's method. I had the
- TheFlyingFiddle (30/89) Jan 30 2014 You can already do this using the Non-virtual interface ideom
- "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> (4/4) Jan 30 2014 Compiling with DMD 2.064, I am NOT able to get any function in
- TheFlyingFiddle (4/8) Jan 30 2014 Yes the void baz() method is incorrect. The rest should be fine
- Frustrated (9/118) Jan 30 2014 But this is not what I am talking about. Obviously one could use
- John Chapman (2/6) Jan 30 2014 It would work if you changed the interface to an abstract class.
- Frustrated (3/10) Jan 30 2014 But then you break the whole usage of interfaces. (multiple
- Steven Schveighoffer (9/12) Jan 30 2014 Yes. Interfaces have no concrete vtable. Only classes do. A concrete cla...
- Frustrated (23/38) Jan 30 2014 Basically I see no reason why the compiler can't treat the
- Steven Schveighoffer (5/9) Jan 30 2014 It's simpler than that. A function is a block of code. A vtable entry
- Frustrated (23/35) Jan 30 2014 Right, this was my original point and why I thought there was
- Steven Schveighoffer (8/45) Jan 30 2014 I think your original example should not have happened. Either there was...
- Frustrated (44/82) Jan 30 2014 Well, as usual, it is almost surely user error. I can't reproduce
- Steven Schveighoffer (3/34) Jan 30 2014 http://dlang.org/phobos/std_typecons.html#.BlackHole
- Steven Schveighoffer (5/6) Jan 30 2014 Sorry, black hole just does nothing. it's white hole you want:
- Frustrated (13/25) Jan 30 2014 But what if you want to provide some default behavior? We are not
- Steven Schveighoffer (42/69) Jan 30 2014 The interface defines the vtable, the class contains a value for that
- Frustrated (42/121) Jan 30 2014 But what I think you are failing to realize is that regardless
- Steven Schveighoffer (25/63) Jan 30 2014 But what if it does need an object?
- Frustrated (21/102) Jan 30 2014 I've said many times that the functions could not use this. If
- Steven Schveighoffer (3/7) Jan 30 2014 OK, then. With that, I shall retire from this discussion :)
- Frustrated (9/19) Jan 30 2014 It would be nice if you could understand what I'm getting at but
- Frustrated (10/10) Jan 30 2014 Simple question.
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
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
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
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
On Thursday, 30 January 2014 at 11:29:55 UTC, TheFlyingFiddle wrote:On Thursday, 30 January 2014 at 11:19:58 UTC, Frustrated wrote: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?)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
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
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:But then you break the whole usage of interfaces. (multiple inheritance issue)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
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
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: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?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
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
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: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)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
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:I think your original example should not have happened. Either there was a bug in the runtime, compiler, or your memory :)On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated <c1514843 drdrb.com> wrote: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).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. -SteveIt 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
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:Well, as usual, it is almost surely user error. I can't reproduce it so we'll just go with that.On Thursday, 30 January 2014 at 17:11:24 UTC, Steven Schveighoffer wrote:I think your original example should not have happened. Either there was a bug in the runtime, compiler, or your memory :)On Thu, 30 Jan 2014 11:58:15 -0500, Frustrated <c1514843 drdrb.com> wrote: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).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. -SteveNo, 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.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!
Jan 30 2014
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:-SteveThis 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 }
Jan 30 2014
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
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: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?)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
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: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. -SteveOn Thu, 30 Jan 2014 11:58:15 -0500, Frustrated <c1514843 drdrb.com> wrote: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?)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
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: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.On Thursday, 30 January 2014 at 17:11:24 UTC, Steven Schveighoffer wrote: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. -SteveOn Thu, 30 Jan 2014 11:58:15 -0500, Frustrated <c1514843 drdrb.com> wrote: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?)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
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 what if it does need an object? interface A { void foo() { bar();} // need 'this' to call bar void bar(); }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).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
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: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.On Thursday, 30 January 2014 at 20:17:23 UTC, Steven Schveighoffer wrote:But what if it does need an object? interface A { void foo() { bar();} // need 'this' to call bar void bar(); }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).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)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.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.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.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...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
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
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: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 ;)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
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