digitalmars.D.learn - private method in interface
- Michael Shulman (17/17) Jun 02 2011 Hi,
- Steven Schveighoffer (8/23) Jun 02 2011 Private methods are non-virtual, so I'm pretty sure they are not suppose...
- Michael Shulman (12/17) Jun 02 2011 In section 6.9.1 of "The D Programming Language" about Non-Virtual
- Steven Schveighoffer (20/40) Jun 02 2011 I'm not sure, I don't have a copy of the book, so I'm not sure of the
- Jonathan M Davis (4/25) Jun 02 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4542
- Kagamin (2/4) Jun 02 2011 Nothing prevents compiler from considering class private methods as fina...
- Jonathan M Davis (6/13) Jun 02 2011 It would be possible but inconsistent. It would also likely be more
- Michael Shulman (16/18) Jun 03 2011 Speaking as a newbie with very little D experience, the idea of
- Michael Shulman (8/10) Jun 02 2011 Thank you! I think this answers my question completely; I just need
- Jonathan M Davis (14/24) Jun 02 2011 http://erdani.com/tdpl/errata/index.php?title=Main_Page
- Michael Shulman (2/25) Jun 02 2011
- Jonathan M Davis (18/36) Jun 03 2011 Actually, C++ has exactly this behavior. You can overload private functi...
- Michael Shulman (4/13) Jun 03 2011 Okay. Then I don't quite understand the rationale for all private
- Jonathan M Davis (30/45) Jun 03 2011 Efficiency. Virtual calls cost more than non-virtual calls. And if you'r...
- Michael Shulman (11/13) Jun 03 2011 Well, it makes perfect sense to me, once given that in D, 'private'
- Jacob Carlborg (6/19) Jun 04 2011 The current implementation of "package" is non-virtual and, as far as I
- Jonathan M Davis (14/28) Jun 03 2011 I would expect package to be virtual, but Walter could have implemented ...
- Michael Shulman (24/28) Jun 03 2011 It appears that overriding a non-virtual, non-abstract method (private
- Michael Shulman (3/31) Jun 03 2011 The bug report appears to already exist:
- Jonathan M Davis (5/41) Jun 03 2011 Try to compile with -w. My guess is that you will get a compiler error. ...
- Michael Shulman (2/3) Jun 03 2011 Nope.
- Jonathan M Davis (6/10) Jun 03 2011 Then file a bug report on it. As I understand it, overriding a non-virtu...
Hi, The following code fails the linker, complaining about an undefined reference to 'foo': interface A { private int foo(); } class B { int bar(A x) { return x.foo(); } } void main() { } But if I remove the 'private' qualifier on 'foo', then it succeeds. Shouldn't B.bar() be able to access the private A.foo(), since they are in the same package? If I move the definition of A into another package, then the *compiler* fails with "interface member not accessible", as I would expect. Thanks! Mike
Jun 02 2011
On Thu, 02 Jun 2011 13:10:14 -0400, Michael Shulman <viritrilbia gmail.com> wrote:Hi, The following code fails the linker, complaining about an undefined reference to 'foo': interface A { private int foo(); } class B { int bar(A x) { return x.foo(); } } void main() { } But if I remove the 'private' qualifier on 'foo', then it succeeds. Shouldn't B.bar() be able to access the private A.foo(), since they are in the same package? If I move the definition of A into another package, then the *compiler* fails with "interface member not accessible", as I would expect.Private methods are non-virtual, so I'm pretty sure they are not supposed to be allowed in an interface. But I suppose private could also mean private final, in which case you have to provide an implementation for foo in the interface. This would be in line with the error message. -Steve
Jun 02 2011
On Thu, Jun 2, 2011 at 10:31 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:Private methods are non-virtual, so I'm pretty sure they are not supposed to be allowed in an interface. But I suppose private could also mean private final, in which case you have to provide an implementation for foo in the interface.In section 6.9.1 of "The D Programming Language" about Non-Virtual Interfaces, there is an example (p214) of an interface which defines two private methods without implementation. But now that you point it out, that code also fails the linker for me. Is that book out of sync with the implementation?This would be in line with the error message.It is true that if I replace "private" with "final" I get the same error message. That is also puzzling to me; I would expect a final method in an interface without an implementation to be a *compiler* error, since there is no way anyone else can implement it. Is there? Mike
Jun 02 2011
On Thu, 02 Jun 2011 15:01:31 -0400, Michael Shulman <viritrilbia gmail.com> wrote:On Thu, Jun 2, 2011 at 10:31 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:I'm not sure, I don't have a copy of the book, so I'm not sure of the context. I remember reading posts claiming that the book intends for private methods to be virtual, but I can't be sure. All I know is, the official position of D is that the book overrules the current spec/implementation. So if it seems the book is not agreeing with the current spec, it's likely a bug in the spec/compiler. If you believe this to be the case, please file a bug on bugzilla http://d.puremagic.com/issues/enter_bug.cgi Put [TDPL] at the beginning of the summary.Private methods are non-virtual, so I'm pretty sure they are not supposed to be allowed in an interface. But I suppose private could also mean private final, in which case you have to provide an implementation for foo in the interface.In section 6.9.1 of "The D Programming Language" about Non-Virtual Interfaces, there is an example (p214) of an interface which defines two private methods without implementation. But now that you point it out, that code also fails the linker for me. Is that book out of sync with the implementation?In D, you do not need to provide an implementation when declaring a function. For example, if you want to hide the details of a function, you can just declare it in a public file, but actually build your library with a private file that contains the implementation. This way, the end-user cannot see the source. .di files are supposed to be for this, but I think in practice, .di and .d files are treated the same by the compiler. You can see a great example of this in object.di included with the compiler (src/druntime/import/object.di). -SteveThis would be in line with the error message.It is true that if I replace "private" with "final" I get the same error message. That is also puzzling to me; I would expect a final method in an interface without an implementation to be a *compiler* error, since there is no way anyone else can implement it. Is there?
Jun 02 2011
On 2011-06-02 12:01, Michael Shulman wrote:On Thu, Jun 2, 2011 at 10:31 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:http://d.puremagic.com/issues/show_bug.cgi?id=4542 http://d.puremagic.com/issues/show_bug.cgi?id=2051 - Jonathan M DavisPrivate methods are non-virtual, so I'm pretty sure they are not supposed to be allowed in an interface. But I suppose private could also mean private final, in which case you have to provide an implementation for foo in the interface.In section 6.9.1 of "The D Programming Language" about Non-Virtual Interfaces, there is an example (p214) of an interface which defines two private methods without implementation. But now that you point it out, that code also fails the linker for me. Is that book out of sync with the implementation?This would be in line with the error message.It is true that if I replace "private" with "final" I get the same error message. That is also puzzling to me; I would expect a final method in an interface without an implementation to be a *compiler* error, since there is no way anyone else can implement it. Is there?
Jun 02 2011
Jonathan M Davis Wrote:http://d.puremagic.com/issues/show_bug.cgi?id=4542 http://d.puremagic.com/issues/show_bug.cgi?id=2051Nothing prevents compiler from considering class private methods as final and allow implement interface private methods (possibly with requirement for `override` keyword).
Jun 02 2011
On 2011-06-02 23:53, Kagamin wrote:Jonathan M Davis Wrote:It would be possible but inconsistent. It would also likely be more complicated to implement than simply making private functions virtual and overridable. I don't really like the idea of private functions being virtual by default though, so maybe your suggestion would be a good one. - Jonathan M Davishttp://d.puremagic.com/issues/show_bug.cgi?id=4542 http://d.puremagic.com/issues/show_bug.cgi?id=2051Nothing prevents compiler from considering class private methods as final and allow implement interface private methods (possibly with requirement for `override` keyword).
Jun 02 2011
On Thu, Jun 2, 2011 at 11:55 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:I don't really like the idea of private functions being virtual by default though, so maybe your suggestion would be a good one.Speaking as a newbie with very little D experience, the idea of private functions being non-virtual would make perfect sense to me if 'private' meant restricted to a single class, as it does in C++. The situation of a derived class being able to override a private function from an interface or base class, but not *call* the overridden function, seems a bit weird and pointless; using 'protected' does make more sense to me for that use case. However, given that in D, 'private' only means restricted to a *module*, it's less clear to me why private functions should be singled out as non-virtual. I might want certain methods to be accessible only within a given module, but still allow them to be overridden within a class hierarchy that exists entirely inside that module. Unless the point of view is that each class should always exist in its own module? Mike
Jun 03 2011
On Thu, Jun 2, 2011 at 12:20 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:http://d.puremagic.com/issues/show_bug.cgi?id=4542 http://d.puremagic.com/issues/show_bug.cgi?id=2051Thank you! I think this answers my question completely; I just need to change "private" to "protected". Is there a place on the web recording "errata" of this sort for TDPL? Here is a related question which puzzles me, from reading http://d-programming-language.org/function.html#virtual-functions What is the difference between "private" and "final private"? Mike
Jun 02 2011
On 2011-06-02 12:59, Michael Shulman wrote:On Thu, Jun 2, 2011 at 12:20 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:http://erdani.com/tdpl/errata/index.php?title=Main_Pagehttp://d.puremagic.com/issues/show_bug.cgi?id=4542 http://d.puremagic.com/issues/show_bug.cgi?id=2051Thank you! I think this answers my question completely; I just need to change "private" to "protected". Is there a place on the web recording "errata" of this sort for TDPL?Here is a related question which puzzles me, from reading http://d-programming-language.org/function.html#virtual-functions What is the difference between "private" and "final private"?At present, there is no difference between a member function which is private and one which is final private. All private functions are non-virtual and are not overridable. So, final does nothing. If/When dmd is updated to match TDPL and make private functions virtual and overridable, then private functions _will_ be virtual and overridable, and final will be required in order to make them non-overridable again (and assuming that the private function in question does not override a private funtion from a base class, the compiler should be able to optimize it so that it's non-virtual just like private currently is). But for now, putting final on a private function does nothing. - Jonathan M Davis
Jun 02 2011
Thanks! On Thu, Jun 2, 2011 at 2:36 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:On 2011-06-02 12:59, Michael Shulman wrote:On Thu, Jun 2, 2011 at 12:20 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:http://erdani.com/tdpl/errata/index.php?title=Main_Pagehttp://d.puremagic.com/issues/show_bug.cgi?id=4542 http://d.puremagic.com/issues/show_bug.cgi?id=2051Thank you! I think this answers my question completely; I just need to change "private" to "protected". Is there a place on the web recording "errata" of this sort for TDPL?Here is a related question which puzzles me, from reading http://d-programming-language.org/function.html#virtual-functions What is the difference between "private" and "final private"?At present, there is no difference between a member function which is private and one which is final private. All private functions are non-virtual and are not overridable. So, final does nothing. If/When dmd is updated to match TDPL and make private functions virtual and overridable, then private functions _will_ be virtual and overridable, and final will be required in order to make them non-overridable again (and assuming that the private function in question does not override a private funtion from a base class, the compiler should be able to optimize it so that it's non-virtual just like private currently is). But for now, putting final on a private function does nothing. - Jonathan M Davis
Jun 02 2011
On 2011-06-03 11:13, Michael Shulman wrote:On Thu, Jun 2, 2011 at 11:55 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:Actually, C++ has exactly this behavior. You can overload private functions in C++. That's where the whole Non-Virtual Interface paradigm came from, I believe. However, in C++, functions are only virtual if you make them virtual (which you don't normally do with private functions unless you're doing NVI), unlike D.I don't really like the idea of private functions being virtual by default though, so maybe your suggestion would be a good one.Speaking as a newbie with very little D experience, the idea of private functions being non-virtual would make perfect sense to me if 'private' meant restricted to a single class, as it does in C++. The situation of a derived class being able to override a private function from an interface or base class, but not *call* the overridden function, seems a bit weird and pointless; using 'protected' does make more sense to me for that use case.However, given that in D, 'private' only means restricted to a *module*, it's less clear to me why private functions should be singled out as non-virtual. I might want certain methods to be accessible only within a given module, but still allow them to be overridden within a class hierarchy that exists entirely inside that module. Unless the point of view is that each class should always exist in its own module?No, there would be nothing wrong with overriding private member functions within a module with derived classes (assuming that private were overridable). That would be a bit weird, generally-speaking, but it would be perfectly legitimate. There are no restrictions on how many classes or structs you put in a module, and the core D community does not seem to think that code should necessarily be divided that way. For instance, both std.container and std.datetime in Phobos have multiple types defined within them. So, you could define as many classes or structs in a module as you want to. The main issue would be if the module got too large (which some have accussed std.datetime of doing). - Jonathan M Davis
Jun 03 2011
On Fri, Jun 3, 2011 at 11:22 AM, Jonathan M Davis <jmdavisProg gmx.com> wrote:Okay. Then I don't quite understand the rationale for all private functions being non-virtual. MikeHowever, given that in D, 'private' only means restricted to a *module*, it's less clear to me why private functions should be singled out as non-virtual. I might want certain methods to be accessible only within a given module, but still allow them to be overridden within a class hierarchy that exists entirely inside that module. Unless the point of view is that each class should always exist in its own module?No, there would be nothing wrong with overriding private member functions within a module with derived classes (assuming that private were overridable).
Jun 03 2011
On 2011-06-03 11:59, Michael Shulman wrote:On Fri, Jun 3, 2011 at 11:22 AM, Jonathan M Davis <jmdavisProg gmx.com>wrote:Efficiency. Virtual calls cost more than non-virtual calls. And if you're never going to override a function, why have it be virtual and incur that extra cost? C++ defaults to non-virtual and has the virtual modifier for making functions virtual, which gives you the efficiency by default with the flexibility to make them virtual if you want to. The problem is that it's still possible to override non-virtual functions, which is almost always a bug. Java took the route of making all functions virtual except where the compiler optimizes them to be non-virtual. D did the same except for private functions, likely on the theory that you basically never override private functions, so why incur the cost? And if you don't know about NVI, having a virtual private function is just plain weird. Lots of people are surprised to find out that it's legal to override private functions like that in C++. So, in most cases, you don't want virtual private functions. The overridability is generally useless and it costs more to call them. Worse, they can't be inlined, because the call is polymorphic and you don't know whether the version of the function in the current class or one in a derived class will be called. The one exception as far as usefulness goes is the NVI idiom, and TDPL said that you could do it (I think because Andrei didn't realize that you couldn't rather than because it was intended to be changed in the language). However, you can still effectively do NVI with protected functions, so arguably, the costs to making private functions virtual far outweigh the benefits. But the fact that TDPL says that private is overridable for NVI may make it so that the language is changed to allow it. We'll have to see. In any case, the reason that you don't normally want private functions to be virtual is because virtual functions cannot generally be inlined and are less efficient than non-virtual functions. - Jonathan M DavisOkay. Then I don't quite understand the rationale for all private functions being non-virtual.However, given that in D, 'private' only means restricted to a *module*, it's less clear to me why private functions should be singled out as non-virtual. I might want certain methods to be accessible only within a given module, but still allow them to be overridden within a class hierarchy that exists entirely inside that module. Unless the point of view is that each class should always exist in its own module?No, there would be nothing wrong with overriding private member functions within a module with derived classes (assuming that private were overridable).
Jun 03 2011
On Fri, Jun 3, 2011 at 1:02 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:And if you don't know about NVI, having a virtual private function is just plain weird.Well, it makes perfect sense to me, once given that in D, 'private' allows access from anywhere in the same module, rather than only in the defining class. I agree that it's weird and surprising in C++. Are 'package' qualified functions also non-virtual? The documentation http://d-programming-language.org/function.html#virtual-functions says that "all non-static non-private non-template member functions are virtual", but I get the same sort of linker errors with 'package' functions that I do with 'private' ones, even with code that's all in one module. Mike
Jun 03 2011
On 2011-06-03 23:55, Michael Shulman wrote:On Fri, Jun 3, 2011 at 1:02 PM, Jonathan M Davis<jmdavisProg gmx.com> wrote:The current implementation of "package" is non-virtual and, as far as I know, has always been like that. What it's actually supposed to be, I don't know. -- /Jacob CarlborgAnd if you don't know about NVI, having a virtual private function is just plain weird.Well, it makes perfect sense to me, once given that in D, 'private' allows access from anywhere in the same module, rather than only in the defining class. I agree that it's weird and surprising in C++. Are 'package' qualified functions also non-virtual? The documentation http://d-programming-language.org/function.html#virtual-functions says that "all non-static non-private non-template member functions are virtual", but I get the same sort of linker errors with 'package' functions that I do with 'private' ones, even with code that's all in one module. Mike
Jun 04 2011
On 2011-06-03 14:55, Michael Shulman wrote:On Fri, Jun 3, 2011 at 1:02 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:I would expect package to be virtual, but Walter could have implemented it as non-virtual on the theory that if you wanted it to be overridden, it would be protected (which would be the normal thing to do when you intend to have a derived class override a member function). I'd suggest opening a bug report. It wouldn't hurt my feelings any if private and package were both always non- virtual, but TDPL says that they're both virtual, and the online docs says that package is virtual, so either the compiler needs to be fixed or TDPL and the docs need to be changed. Regardless, I would have hoped that you'd get an error at compile time about overriding a non-virtual function if package is non-virtual, so at minimum, the error message needs to be improved. So, open a bug report on it, and Walter can make whatever changes are appropriate. - Jonathan M DavisAnd if you don't know about NVI, having a virtual private function is just plain weird.Well, it makes perfect sense to me, once given that in D, 'private' allows access from anywhere in the same module, rather than only in the defining class. I agree that it's weird and surprising in C++. Are 'package' qualified functions also non-virtual? The documentation http://d-programming-language.org/function.html#virtual-functions says that "all non-static non-private non-template member functions are virtual", but I get the same sort of linker errors with 'package' functions that I do with 'private' ones, even with code that's all in one module.
Jun 03 2011
On Fri, Jun 3, 2011 at 3:07 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:I'd suggest opening a bug report.Okay, will do.Regardless, I would have hoped that you'd get an error at compile time about overriding a non-virtual function if package is non-virtualIt appears that overriding a non-virtual, non-abstract method (private or package) just hides the base-class version when the reference is of derived type, exactly as happens in C++ for non-virtual methods. E.g. class A { private void dostuff() { writeln ("In A.dostuff"); } } class B : A { private void dostuff() { writeln ("In B.dostuff"); } } void main () { B y = new B(); A x = y; y.dostuff(); x.dostuff(); } prints In B.dostuff In A.dostuff I would have kind of hoped for a compiler error too, given that C++ programmers generally seem to feel that overriding non-virtual methods in this way is a bad idea. Mike
Jun 03 2011
The bug report appears to already exist: http://d.puremagic.com/issues/show_bug.cgi?id=3258 On Fri, Jun 3, 2011 at 3:07 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:On 2011-06-03 14:55, Michael Shulman wrote:On Fri, Jun 3, 2011 at 1:02 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:I would expect package to be virtual, but Walter could have implemented it as non-virtual on the theory that if you wanted it to be overridden, it would be protected (which would be the normal thing to do when you intend to have a derived class override a member function). I'd suggest opening a bug report. It wouldn't hurt my feelings any if private and package were both always non- virtual, but TDPL says that they're both virtual, and the online docs says that package is virtual, so either the compiler needs to be fixed or TDPL and the docs need to be changed. Regardless, I would have hoped that you'd get an error at compile time about overriding a non-virtual function if package is non-virtual, so at minimum, the error message needs to be improved. So, open a bug report on it, and Walter can make whatever changes are appropriate. - Jonathan M DavisAnd if you don't know about NVI, having a virtual private function is just plain weird.Well, it makes perfect sense to me, once given that in D, 'private' allows access from anywhere in the same module, rather than only in the defining class. I agree that it's weird and surprising in C++. Are 'package' qualified functions also non-virtual? The documentation http://d-programming-language.org/function.html#virtual-functions says that "all non-static non-private non-template member functions are virtual", but I get the same sort of linker errors with 'package' functions that I do with 'private' ones, even with code that's all in one module.
Jun 03 2011
On 2011-06-03 19:44, Michael Shulman wrote:On Fri, Jun 3, 2011 at 3:07 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:Try to compile with -w. My guess is that you will get a compiler error. But yes, it really should give an error regardless. - Jonathan M DavisI'd suggest opening a bug report.Okay, will do.Regardless, I would have hoped that you'd get an error at compile time about overriding a non-virtual function if package is non-virtualIt appears that overriding a non-virtual, non-abstract method (private or package) just hides the base-class version when the reference is of derived type, exactly as happens in C++ for non-virtual methods. E.g. class A { private void dostuff() { writeln ("In A.dostuff"); } } class B : A { private void dostuff() { writeln ("In B.dostuff"); } } void main () { B y = new B(); A x = y; y.dostuff(); x.dostuff(); } prints In B.dostuff In A.dostuff I would have kind of hoped for a compiler error too, given that C++ programmers generally seem to feel that overriding non-virtual methods in this way is a bad idea.
Jun 03 2011
On Fri, Jun 3, 2011 at 8:54 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:Try to compile with -w. My guess is that you will get a compiler error.Nope.
Jun 03 2011
On 2011-06-03 21:52, Michael Shulman wrote:On Fri, Jun 3, 2011 at 8:54 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:Then file a bug report on it. As I understand it, overriding a non-virtual function in D should be illegal. Certainly, it goes against how D deals with virtuality in general. - Jonathan M DavisTry to compile with -w. My guess is that you will get a compiler error.Nope.
Jun 03 2011