June 03, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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
|
June 03, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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: > > 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. 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. > 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 |
June 03, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
On Fri, Jun 3, 2011 at 11:22 AM, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
>> 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).
Okay. Then I don't quite understand the rationale for all private functions being non-virtual.
Mike
|
June 03, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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: > >> 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). > > Okay. Then I don't quite understand the rationale for all private functions being non-virtual. 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 Davis |
June 03, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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 |
June 03, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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: > > 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. 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 Davis |
June 04, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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-virtual It 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 |
June 04, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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: >> > 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. > > 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 Davis > |
June 04, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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: > > 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-virtual > > It 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. 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 Davis |
June 04, 2011 Re: private method in interface | ||||
---|---|---|---|---|
| ||||
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.
|
Copyright © 1999-2021 by the D Language Foundation