www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Module-level accessibility

reply bearophile <bearophileHUGS lycos.com> writes:
Sergey:

 With a great surprise, I have discovered that from another module it is  
 still possible to access both x1 and C1, though fnc1() is inaccessible !
 Can anyone explain me what does it mean ?

If what you have written is true, and it's easy to test it, then it just means there's another hole (== bug) in the D module system, that needs to be fixed :-) Bye, bearophile
Oct 03 2010
next sibling parent reply Sergey <smsmfk gmail.com> writes:
bearophile, thanks you very much for your answer. I've heard that D has a  
very vibrant community; now I know it really :)

By now, from what I know about D I can draw a conclusion that it's a  
greatly promising language with many innovations and I would say even  
fantastic features and tools (e.g., contract-based programming). But such  
serious bugs that are not fixed yet can disgust any programmer, I think.  
All the more beginning programmers, like me. Probably D2 implementation is  
not grown-up enough yet to be used in projects of a real importance...

On Sun, 03 Oct 2010 17:58:07 +0300, bearophile <bearophileHUGS lycos.com>  
wrote:

 Sergey:

 With a great surprise, I have discovered that from another module it is
 still possible to access both x1 and C1, though fnc1() is inaccessible !
 Can anyone explain me what does it mean ?

If what you have written is true, and it's easy to test it, then it just means there's another hole (== bug) in the D module system, that needs to be fixed :-) Bye, bearophile

-- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 03 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Sergey:

 But such serious bugs that are not fixed yet can disgust any programmer, I
think.

That's a mild bug :-) You can live with it, until it's fixed. There are far worse bugs in DMD now. You can't ask the implementation of a new language to be bug-free. Especially a language that has grown so quickly.
 All the more beginning programmers, like me. Probably D2 implementation is  
 not grown-up enough yet to be used in projects of a real importance...

It's a bootstrap situation: bug get found and fixed while people write larger and larger programs, and people are able to write larger programs because bugs get fixed. At the moment is wrong to use D2 for live-or-death situations, for systems where reliability is critical. But as it gets debugged more and more the scope of its usability will grow. D is designed to eventually be a reliable language, more than C :-) Bye, bearophile
Oct 04 2010
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday 04 October 2010 04:41:53 Sergey wrote:
 Hi bearophile,
 
 you've just cheered me up :-) I'll proceed doing my best to get closer to
 this language.
 By the way, if it's not difficult for you, could you please clarify the
 following:
 
 1) what did you mean by "far worse bugs" :-) just several examples
 2) Andrei Alexandrescu wrote in his book that it's possible to make
 non-final methods of interfaces private, and then override them in derived
 classes. There are even examples in his book that demonstrate this. At the
 same time, current DMD documentation pretty clear says that nothing
 private can be overridden.

http://d.puremagic.com/issues/show_bug.cgi?id=4542 The current dmd is not entirely in line with TPDL. In almost all cases, however, that means that dmd needs to be fixed, so TDPL will be correct. But unfortunately, there are things that TDPL says which aren't true yet. This is one of them. Another one would be being able to have multiple alias this for a single struct or class - right now you're restricted to one. Supposedly, bugs which have to do with dmd not matcthing TDPL have TDPL in their name (though sometimes they don't), so if you search for TDPL in bugzilla, you should find a good chunk of them. - Jonathan M Davis
Oct 04 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/4/10 10:47 CDT, Jonathan M Davis wrote:
 On Monday 04 October 2010 04:41:53 Sergey wrote:
 Hi bearophile,

 you've just cheered me up :-) I'll proceed doing my best to get closer to
 this language.
 By the way, if it's not difficult for you, could you please clarify the
 following:

 1) what did you mean by "far worse bugs" :-) just several examples
 2) Andrei Alexandrescu wrote in his book that it's possible to make
 non-final methods of interfaces private, and then override them in derived
 classes. There are even examples in his book that demonstrate this. At the
 same time, current DMD documentation pretty clear says that nothing
 private can be overridden.

http://d.puremagic.com/issues/show_bug.cgi?id=4542 The current dmd is not entirely in line with TPDL. In almost all cases, however, that means that dmd needs to be fixed, so TDPL will be correct. But unfortunately, there are things that TDPL says which aren't true yet. This is one of them. Another one would be being able to have multiple alias this for a single struct or class - right now you're restricted to one. Supposedly, bugs which have to do with dmd not matcthing TDPL have TDPL in their name (though sometimes they don't), so if you search for TDPL in bugzilla, you should find a good chunk of them. - Jonathan M Davis

There is still debate on the matter of private methods in interfaces. Please bring up in this forum any additional pro and con arguments that you might have. Andrei
Oct 04 2010
next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu Wrote:
 
 There is still debate on the matter of private methods in interfaces. 
 Please bring up in this forum any additional pro and con arguments that 
 you might have.

What debate? Private methods don't get a vtbl entry so I don't see how an interface could possibly require one, regardless of in-module visibility.
Oct 04 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/4/10 13:27 CDT, Denis Koroskin wrote:
 On Mon, 04 Oct 2010 22:13:52 +0400, Jonathan M Davis
 <jmdavisProg gmx.com> wrote:

 On Monday, October 04, 2010 10:37:53 Sean Kelly wrote:
 Andrei Alexandrescu Wrote:
 There is still debate on the matter of private methods in interfaces.
 Please bring up in this forum any additional pro and con arguments

 you might have.

What debate? Private methods don't get a vtbl entry so I don't see how an interface could possibly require one, regardless of in-module visibility.

Except that per TDPL private methods are _supposed_ to be in the vtable: http://d.puremagic.com/issues/show_bug.cgi?id=4542 The fact that they don't currently is definitely limiting. Personally, I liked what TDPL said about interfaces and private methods, and I don't know what the debate against them is. It all seemed quite sensible to me. Regardless, however, private methods really should be properly polymorphic. - Jonathan M Davis

I agree. Class A can access private methods of class B as long as both defined in the same module. If it has access to private methods, why can't it override them? Makes little sense, if you ask me, especially given that user may prevent overriding methods using "final" keyword. And the "package" also implying final is just ridiculous!

This is a very good argument that in my mind settles the case. Andrei
Oct 04 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 I agree. Class A can access private methods of class B as long as both
 defined in the same module. If it has access to private methods, why
 can't it override them? Makes little sense, if you ask me, especially
 given that user may prevent overriding methods using "final" keyword.
 And the "package" also implying final is just ridiculous!

This is a very good argument that in my mind settles the case.

I am not expert about this, but ignoring private attributes among classes/structs in the same module may be useful, but it's a dirty thing. If you split in two parts a module that contains two classes that access each other private members, the code stops working. Overriding private methods makes the situation even dirtier. I don't think C#/Java programmers will appreciate this :-) Bye, bearophile
Oct 04 2010
parent reply Jacob Carlborg <doob me.com> writes:
On 2010-10-04 21:37, bearophile wrote:
 Andrei:

 I agree. Class A can access private methods of class B as long as both
 defined in the same module. If it has access to private methods, why
 can't it override them? Makes little sense, if you ask me, especially
 given that user may prevent overriding methods using "final" keyword.
 And the "package" also implying final is just ridiculous!

This is a very good argument that in my mind settles the case.

I am not expert about this, but ignoring private attributes among classes/structs in the same module may be useful, but it's a dirty thing. If you split in two parts a module that contains two classes that access each other private members, the code stops working. Overriding private methods makes the situation even dirtier. I don't think C#/Java programmers will appreciate this :-) Bye, bearophile

If you have two classes in one file in Java you can access private methods from the other class. -- /Jacob Carlborg
Oct 05 2010
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 05/10/2010 08:27, Jacob Carlborg wrote:
 If you have two classes in one file in Java you can access private
 methods from the other class.

Only if one class is nested in the other. -- Bruno Medeiros - Software Engineer
Oct 26 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, October 04, 2010 10:37:53 Sean Kelly wrote:
 Andrei Alexandrescu Wrote:
 There is still debate on the matter of private methods in interfaces.
 Please bring up in this forum any additional pro and con arguments that
 you might have.

What debate? Private methods don't get a vtbl entry so I don't see how an interface could possibly require one, regardless of in-module visibility.

Except that per TDPL private methods are _supposed_ to be in the vtable: http://d.puremagic.com/issues/show_bug.cgi?id=4542 The fact that they don't currently is definitely limiting. Personally, I liked what TDPL said about interfaces and private methods, and I don't know what the debate against them is. It all seemed quite sensible to me. Regardless, however, private methods really should be properly polymorphic. - Jonathan M Davis
Oct 04 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 04 Oct 2010 14:13:52 -0400, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Monday, October 04, 2010 10:37:53 Sean Kelly wrote:
 Andrei Alexandrescu Wrote:
 There is still debate on the matter of private methods in interfaces.
 Please bring up in this forum any additional pro and con arguments  

 you might have.

What debate? Private methods don't get a vtbl entry so I don't see how an interface could possibly require one, regardless of in-module visibility.

Except that per TDPL private methods are _supposed_ to be in the vtable: http://d.puremagic.com/issues/show_bug.cgi?id=4542 The fact that they don't currently is definitely limiting. Personally, I liked what TDPL said about interfaces and private methods, and I don't know what the debate against them is. It all seemed quite sensible to me. Regardless, however, private methods really should be properly polymorphic.

What possible use case could private methods being polymorphic allow? A private method can only be called by the class that contains the implementation. Allowing base classes to call it makes no sense. Make the method protected, it gives the desired effect (including for the example in the bug report as stated by the original reporter). -Steve
Oct 04 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 04 Oct 2010 22:13:52 +0400, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Monday, October 04, 2010 10:37:53 Sean Kelly wrote:
 Andrei Alexandrescu Wrote:
 There is still debate on the matter of private methods in interfaces.
 Please bring up in this forum any additional pro and con arguments  

 you might have.

What debate? Private methods don't get a vtbl entry so I don't see how an interface could possibly require one, regardless of in-module visibility.

Except that per TDPL private methods are _supposed_ to be in the vtable: http://d.puremagic.com/issues/show_bug.cgi?id=4542 The fact that they don't currently is definitely limiting. Personally, I liked what TDPL said about interfaces and private methods, and I don't know what the debate against them is. It all seemed quite sensible to me. Regardless, however, private methods really should be properly polymorphic. - Jonathan M Davis

I agree. Class A can access private methods of class B as long as both defined in the same module. If it has access to private methods, why can't it override them? Makes little sense, if you ask me, especially given that user may prevent overriding methods using "final" keyword. And the "package" also implying final is just ridiculous!
Oct 04 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 04 Oct 2010 22:26:17 +0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Mon, 04 Oct 2010 14:13:52 -0400, Jonathan M Davis  
 <jmdavisProg gmx.com> wrote:

 On Monday, October 04, 2010 10:37:53 Sean Kelly wrote:
 Andrei Alexandrescu Wrote:
 There is still debate on the matter of private methods in interfaces.
 Please bring up in this forum any additional pro and con arguments  

 you might have.

What debate? Private methods don't get a vtbl entry so I don't see how an interface could possibly require one, regardless of in-module visibility.

Except that per TDPL private methods are _supposed_ to be in the vtable: http://d.puremagic.com/issues/show_bug.cgi?id=4542 The fact that they don't currently is definitely limiting. Personally, I liked what TDPL said about interfaces and private methods, and I don't know what the debate against them is. It all seemed quite sensible to me. Regardless, however, private methods really should be properly polymorphic.

What possible use case could private methods being polymorphic allow? A private method can only be called by the class that contains the implementation. Allowing base classes to call it makes no sense. Make the method protected, it gives the desired effect (including for the example in the bug report as stated by the original reporter). -Steve

module private; import std.stdio; class A { private void foo() { writeln("hi there"); } } class B : A { void test() { foo(); } } void main() { B b = new B(); b.test(); } # dmd private.d && ./private hi there!
Oct 04 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 04 Oct 2010 14:29:38 -0400, Denis Koroskin <2korden gmail.com>  
wrote:

 On Mon, 04 Oct 2010 22:26:17 +0400, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:

 What possible use case could private methods being polymorphic allow?

 A private method can only be called by the class that contains the  
 implementation.  Allowing base classes to call it makes no sense.

 Make the method protected, it gives the desired effect (including for  
 the example in the bug report as stated by the original reporter).

 -Steve

module private; import std.stdio; class A { private void foo() { writeln("hi there"); } } class B : A { void test() { foo(); } } void main() { B b = new B(); b.test(); } # dmd private.d && ./private hi there!

That works today (aside from using a keyword for the module name), there's nothing polymorphic about it. I suppose you may be rebutting my "can only be called by the class that contains the implementation", yes, I immediately wished to change that sentence after I sent it out. But you don't need polymorphism to achieve this. -Steve
Oct 04 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 04 Oct 2010 22:13:52 +0400, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Monday, October 04, 2010 10:37:53 Sean Kelly wrote:
 Andrei Alexandrescu Wrote:
 There is still debate on the matter of private methods in interfaces.
 Please bring up in this forum any additional pro and con arguments  

 you might have.

What debate? Private methods don't get a vtbl entry so I don't see how an interface could possibly require one, regardless of in-module visibility.

Except that per TDPL private methods are _supposed_ to be in the vtable: http://d.puremagic.com/issues/show_bug.cgi?id=4542 The fact that they don't currently is definitely limiting. Personally, I liked what TDPL said about interfaces and private methods, and I don't know what the debate against them is. It all seemed quite sensible to me. Regardless, however, private methods really should be properly polymorphic. - Jonathan M Davis

Interesting enough, you can "override" private methods, yet the override keyword is silently ignored: import std.stdio; class A { private void foo() { writeln("A.foo"); } void test() { foo(); } } class B : A { private override void foo() { writeln("B.foo"); } } void main() { B b = new B(); b.test(); } # dmd private.d && ./private A.foo
Oct 04 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 04 Oct 2010 15:14:09 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 10/4/10 13:27 CDT, Denis Koroskin wrote:

 And the "package" also implying final is just ridiculous!


This I agree with.
 I agree. Class A can access private methods of class B as long as both
 defined in the same module. If it has access to private methods, why
 can't it override them? Makes little sense, if you ask me, especially
 given that user may prevent overriding methods using "final" keyword.

This is a very good argument that in my mind settles the case.

I don't understand the objection to using protected? class A { final void pubfunc() { foo(); } protected void foo() {writeln("A");} } class B : A { /*final*/ protected void foo() {writeln("B");} } Make B.foo final if you don't want more derived functions from it. What is the issue with this solution? Note that private functions don't need to be declared in an interface file, but they would have to be if they are in the vtable. My concern is that most of the time a final function isn't meant to be overridden. What you end up with is silent, useless virtualization. We are catering to the (very) uncommon case. I would not object to this being implemented if: A) The compiler only allocated a vtable spot for the function if it was detected to be overridden in a derived class. This is easily detected since the only classes that can override such a function would be in the same module. This still means the private function must appear in the .di file, but only when they are virtual. B) Override was a required term for functions that override others (I know this is planned, but let's get this in there first). I still see no pain because of the current implementation, I'm able to get by just fine. -Steve
Oct 04 2010
prev sibling next sibling parent Sergey <smsmfk gmail.com> writes:
Hi Daniel,

I didn't by no means want to say that D is unusable or unenjoyable because  
of this still-persisting defect. I would say, D2 is too young to be good  
rather than bad. Just.. I considered D to be more mature than it currently  
is. Well, at any rate we need to wait some time.

You say:
"What's the big deal, just don't access private members (it's not like you  
have to) and your code will still work when the bug is fixed.". Ok, it's  
clear. But thinking in this way it's also fine to make all private class  
members public (in C++ for example) and just not to call them from outside  
the class. Nothing will be broken.

Nevertheless, thank you for your reply. I'm glad that my interest about  
this issue is now satisfied.

On Mon, 04 Oct 2010 13:37:13 +0300, Daniel Gibson <metalcaedes gmail.com>  
wrote:

 2010/10/4 Sergey <smsmfk gmail.com>:
 bearophile, thanks you very much for your answer. I've heard that D has  
 a
 very vibrant community; now I know it really :)

 By now, from what I know about D I can draw a conclusion that it's a  
 greatly
 promising language with many innovations and I would say even fantastic
 features and tools (e.g., contract-based programming). But such serious  
 bugs
 that are not fixed yet can disgust any programmer, I think. All the more
 beginning programmers, like me. Probably D2 implementation is not  
 grown-up
 enough yet to be used in projects of a real importance...

Do you really consider this bug (i.e. being able to access private members of another module) so serious or "disgusting" that it makes D unusable (or unenjoyable)? What's the big deal, just don't access private members (it's not like you have to) and your code will still work when the bug is fixed. Cheers, - Daniel

-- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 04 2010
prev sibling next sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
On Mon, Oct 4, 2010 at 1:24 PM, Sergey <smsmfk gmail.com> wrote:
 Hi Daniel,

 I didn't by no means want to say that D is unusable or unenjoyable because
 of this still-persisting defect. I would say, D2 is too young to be good
 rather than bad. Just.. I considered D to be more mature than it currently
 is. Well, at any rate we need to wait some time.

 You say:
 "What's the big deal, just don't access private members (it's not like you
 have to) and your code will still work when the bug is fixed.". Ok, it's
 clear. But thinking in this way it's also fine to make all private class
 members public (in C++ for example) and just not to call them from outside
 the class. Nothing will be broken.

No, it's not the same. 1. making them private indicates that you don't want them to be used outside of the module. Even if this is not currently enforced, your intention is clear. 2. As mentioned before, this *is* clearly a bug that should be fixed and I guess it will be fixed (shouldn't be that hard). And when it's fixed, code that "uses" this bug will break - so it's not the same as just making it public and rely on it not being used anyway. I'm just saying that this bug doesn't make D less usable. When writing code you usually don't try accessing private members from the outside anyway, because you don't expect that to work. And it seems like you're the first one to discover the bug so apparently nobody tried that before (or, if he did, didn't file a bug report). IMHO there are two kinds of bugs: 1. Something you expect to work (and that should, by specification, work) doesn't work. That's the bad kind and should be fixed as soon as possible. 2. Something you don't expected to work (and shouldn't, by specification) *does* work. That's the kind we're having here and IMHO it's not as bad, because it doesn't impair the usefulness of the tool (in this case the D compiler). Of course it should be fixed anyway before people consider it a feature and use it, but is probably has a lower priority.
Oct 04 2010
prev sibling next sibling parent Sergey <smsmfk gmail.com> writes:
Hi bearophile,

you've just cheered me up :-) I'll proceed doing my best to get closer to  
this language.
By the way, if it's not difficult for you, could you please clarify the  
following:

1) what did you mean by "far worse bugs" :-) just several examples
2) Andrei Alexandrescu wrote in his book that it's possible to make  
non-final methods of interfaces private, and then override them in derived  
classes. There are even examples in his book that demonstrate this. At the  
same time, current DMD documentation pretty clear says that nothing  
private can be overridden.

Best regards,
Sergey.

On Mon, 04 Oct 2010 14:03:14 +0300, bearophile <bearophileHUGS lycos.com>  
wrote:

 Sergey:

 But such serious bugs that are not fixed yet can disgust any  
 programmer, I think.

That's a mild bug :-) You can live with it, until it's fixed. There are far worse bugs in DMD now. You can't ask the implementation of a new language to be bug-free. Especially a language that has grown so quickly.
 All the more beginning programmers, like me. Probably D2 implementation  
 is
 not grown-up enough yet to be used in projects of a real importance...

It's a bootstrap situation: bug get found and fixed while people write larger and larger programs, and people are able to write larger programs because bugs get fixed. At the moment is wrong to use D2 for live-or-death situations, for systems where reliability is critical. But as it gets debugged more and more the scope of its usability will grow. D is designed to eventually be a reliable language, more than C :-) Bye, bearophile

-- Using Opera's revolutionary email client: http://www.opera.com/mail/
Oct 04 2010
prev sibling parent reply Don <nospam nospam.com> writes:
Daniel Gibson wrote:
 2010/10/4 Sergey <smsmfk gmail.com>:
 bearophile, thanks you very much for your answer. I've heard that D has a
 very vibrant community; now I know it really :)

 By now, from what I know about D I can draw a conclusion that it's a greatly
 promising language with many innovations and I would say even fantastic
 features and tools (e.g., contract-based programming). But such serious bugs
 that are not fixed yet can disgust any programmer, I think. All the more
 beginning programmers, like me. Probably D2 implementation is not grown-up
 enough yet to be used in projects of a real importance...

Do you really consider this bug (i.e. being able to access private members of another module) so serious or "disgusting" that it makes D unusable (or unenjoyable)? What's the big deal, just don't access private members (it's not like you have to) and your code will still work when the bug is fixed. Cheers, - Daniel

I think he's concerned (quite rightly) that discovering such a significant unfixed bug indicates that the compiler is poor quality. It's actually bug 314, which is infamous and by far the most voted bug in Bugzilla. It's important more because it looks bad, than because of the impact that it has in practice. It's one of three remaining bugs which I've rated as showstoppers -- that is, a single bug that is so terrible or high-profile that people may lose interest in the language because of it alone. (The others are bug 3516 and 2451). However, it's not really indicative of the state of the compiler. There are very few bugs which are even half as serious. You don't have to go very far down the list of most-voted bugs before you get to things which are merely annoying.
Oct 04 2010
parent Juanjo Alvarez <fake fakeemail.com> writes:
On Mon, 04 Oct 2010 14:28:32 +0200, Don <nospam nospam.com> wrote:
 may lose interest in the language because of it alone. (The others 

 bug 3516 and 2451).

Eh, I was bitten but 2451 yesterday and actually had to change a lot of function signatures and rethink my code to avoid it. I hope is fixed soon. On the other hand, programming with the current state of the D2 compiler is a good mental exercise because you never know when you'll have to redesign something. It's the closer most programmers can get of an extreme sport , I guess.
Oct 04 2010
prev sibling next sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
2010/10/4 Sergey <smsmfk gmail.com>:
 bearophile, thanks you very much for your answer. I've heard that D has a
 very vibrant community; now I know it really :)

 By now, from what I know about D I can draw a conclusion that it's a greatly
 promising language with many innovations and I would say even fantastic
 features and tools (e.g., contract-based programming). But such serious bugs
 that are not fixed yet can disgust any programmer, I think. All the more
 beginning programmers, like me. Probably D2 implementation is not grown-up
 enough yet to be used in projects of a real importance...

Do you really consider this bug (i.e. being able to access private members of another module) so serious or "disgusting" that it makes D unusable (or unenjoyable)? What's the big deal, just don't access private members (it's not like you have to) and your code will still work when the bug is fixed. Cheers, - Daniel
Oct 04 2010
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday 04 October 2010 11:26:17 Steven Schveighoffer wrote:
 What possible use case could private methods being polymorphic allow?
 
 A private method can only be called by the class that contains the
 implementation.  Allowing base classes to call it makes no sense.
 
 Make the method protected, it gives the desired effect (including for the
 example in the bug report as stated by the original reporter).
 
 -Steve

It allows for the non-virtual interface pattern. You declare a final public function on the base clase which calls a private virtual one (which is probably abstract). Derived classes then override the private virtual method. This allows the base class to enforce things about the private virtual method - for instance pre and post conditions on the public final method would then always apply to the private virtual method. Only the base class can actually call the private virtual method, but it still allows for the derived classes to override its functionality. It's a useful idiom which D doens't currently support but which TDPL specifically discusses and claims that D supports. Take at look at these for more info: http://www.gotw.ca/publications/mill18.htm http://en.wikibooks.org/wiki/More_C++_Idioms/Non-Virtual_Interface - Jonathan M Davis
Oct 04 2010
parent reply Jacob Carlborg <doob me.com> writes:
On 2010-10-05 00:11, Steven Schveighoffer wrote:
 On Mon, 04 Oct 2010 17:54:54 -0400, Jonathan M Davis
 <jmdavisProg gmx.com> wrote:

 On Monday, October 04, 2010 13:41:38 Steven Schveighoffer wrote:
 To me, making it private doesn't do anything over protected. A derived
 class can still call the function in question, because it has the
 implementation. I don't see what the point is...

 A derived class from the derivative doesn't have access, but it can
 always
 override it in order to be able to call it (not a good workaround to
 require).

Except that part of the point is that because the private method is private in the base class, it _can't_ be called by derived classes. It can only be overridden.

Sure you can. Altered version of code from one of your articles: #include <set> class Set { std::set<int> s_; public: void add (int i) { s_.insert (i); add_impl (i); // Note virtual call. } void addAll (int * begin, int * end) { s_.insert (begin, end); // --------- (1) addAll_impl (begin, end); // Note virtual call. } private: virtual void add_impl (int i) = 0; virtual void addAll_impl (int * begin, int * end) = 0; }; class CountingSet : public Set { private: int count_; virtual void add_impl (int i) { addAll_impl(&i, (&i) + 1); // hey look, we can call a private method! } virtual void addAll_impl (int * begin, int * end) { count_ += std::distance(begin,end); } }; compiles with g++. So the private restriction does nothing significant IMO. Not responding to the rest of your points, since my argument is predicated on you understanding this first ;) In this example, BTW, I think the significance of private is the fact that the s_ member is private. That *does* prevent derived classes from altering the set except through the common interface. Also, note that I'm not saying NVI isn't a valid or useful pattern (I've used it in the past with success). I just think protected is a better choice for the virtual methods. -Steve

Who says we need to implement it as g++ does? DMD could implement it to not allow that. -- /Jacob Carlborg
Oct 05 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/5/10 7:40 CDT, Steven Schveighoffer wrote:
 On Tue, 05 Oct 2010 03:25:03 -0400, Jacob Carlborg <doob me.com> wrote:

 Who says we need to implement it as g++ does? DMD could implement it
 to not allow that.

The derived class controls everything. You cannot take control away from the derived class, it just can't be done: class A { private void cantCallMe(); } class B : A { override private void cantCallMe() { butICanCallYou(); } private void butICanCallYou() { /* do impl */ } } so far, private virtual functions == annoyance. I haven't seen anything to prove otherwise yet. -Steve

Private overridable functions come with a guarantee that hooks can never be called from an unknown/uncontrolled context. Andrei
Oct 05 2010
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday 05 October 2010 09:42:14 Steven Schveighoffer wrote:
 And when would a protected hook be callable from an unknown/uncontrolled
 context?  In whose eyes, the base or derived class?
 
 The thing is, any class that defines a private function implementation is
 able to call it.  You can't prevent that.  So in the eyes of any base
 class, it has no way to restrict that.  In the eyes of the derived class,
 it has no control over whether a base class can call it or not.
 Essentially a private overridable function has one additional guarantee
 over a protected function -- a derived class cannot call it if it hasn't
 defined its own version (and isn't in the same module).  But that's not
 the property desired, the property desired for NVI is that *nobody* can
 call it except the base class, even derived classes.  That's simply not
 possible.  So we have to pretend that we can't call it, which is fine,
 just as easy with protected.
 
 Consider this:
 
 abstract class A
 {
    public void myAPIFn() { foo(); }
    abstract private void foo();
 }
 
 abstract class B : A
 {
    public void bar() {myAPIFn();}
 }
 
 class C : B
 {
    private void foo() {}
 }
 
 So good so far.  But I can alter B so it can circumvent myAPIFn by adding
 its own implementation for foo (which does nothing), and now I'm able to
 call foo directly from myAPIFn.  Basically, even though B does not intend
 for its version of foo to be the real implementation (knowing that it's
 abstract and must be derived), it can hijack A's ability to funnel all
 calls through myAPIFn by simply adding a blank function.
 
 I just don't see the benefit over protected anywhere.  You can't say
 "you're allowed to define this, but you're not allowed to call it."  That
 makes no sense at all, and as I've shown, is impossible to enforce.

Well, I don't see why it wouldn't be possible for the compiler to enforce that overridden private methods can't be called by anyone but the base class. That being the case, then allowing for private virtual functions is most definitely useful. However, if it really isn't possible to restrict it so that derived classes can't call the private methods that they've overridden, then I do agree that we might as well just stick to using protected and make private functions unoverridable. But if we _can_ make it so that derived classes can't call overridden private methods, I think that that would be valuable and desirable. - Jonathan M Davis
Oct 05 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 05 Oct 2010 20:27:58 -0400, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 Well, I don't see why it wouldn't be possible for the compiler to  
 enforce that
 overridden private methods can't be called by anyone but the base class.  
 That
 being the case, then allowing for private virtual functions is most  
 definitely
 useful. However, if it really isn't possible to restrict it so that  
 derived
 classes can't call the private methods that they've overridden, then I  
 do agree
 that we might as well just stick to using protected and make private  
 functions
 unoverridable. But if we _can_ make it so that derived classes can't call
 overridden private methods, I think that that would be valuable and  
 desirable.

See my earlier post -- if you control the implementation, the compiler cannot prevent you from calling it. Even if it tries... http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=118350 So you gain nothing, but annoyance (*grumble* now I have to split my implementation from the virtual function just to be able to call it?). -Steve
Oct 06 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 04 Oct 2010 16:14:44 -0400, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Monday 04 October 2010 11:26:17 Steven Schveighoffer wrote:
 What possible use case could private methods being polymorphic allow?

 A private method can only be called by the class that contains the
 implementation.  Allowing base classes to call it makes no sense.

 Make the method protected, it gives the desired effect (including for  
 the
 example in the bug report as stated by the original reporter).

 -Steve

It allows for the non-virtual interface pattern. You declare a final public function on the base clase which calls a private virtual one (which is probably abstract). Derived classes then override the private virtual method. This allows the base class to enforce things about the private virtual method - for instance pre and post conditions on the public final method would then always apply to the private virtual method. Only the base class can actually call the private virtual method, but it still allows for the derived classes to override its functionality. It's a useful idiom which D doens't currently support but which TDPL specifically discusses and claims that D supports. Take at look at these for more info: http://www.gotw.ca/publications/mill18.htm http://en.wikibooks.org/wiki/More_C++_Idioms/Non-Virtual_Interface

To me, making it private doesn't do anything over protected. A derived class can still call the function in question, because it has the implementation. I don't see what the point is... A derived class from the derivative doesn't have access, but it can always override it in order to be able to call it (not a good workaround to require). Not to mention that you can't call the parent class' version, so you can't keep that behavior intact. I see nothing but annoyance for using private virtual functions. -Steve
Oct 04 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, October 04, 2010 13:41:38 Steven Schveighoffer wrote:
 To me, making it private doesn't do anything over protected.  A derived
 class can still call the function in question, because it has the
 implementation.  I don't see what the point is...
 
 A derived class from the derivative doesn't have access, but it can always
 override it in order to be able to call it (not a good workaround to
 require). 

Except that part of the point is that because the private method is private in the base class, it _can't_ be called by derived classes. It can only be overridden.
 Not to mention that you can't call the parent class' version,
 so you can't keep that behavior intact.

For some situations, that could be annoying, but there are plenty of cases where that wouldn't matter. And I suspect that in many cases when NVI is used, it's really only intended that there be one derived class anyway. So, the fact that base class versions of the private function can't be called would be irrelevant.
 I see nothing but annoyance for using private virtual functions.

Well, no one says that you have to use it (though obviously, if it's possible, and you're working with other people in D, you could be forced to use it because someone else did in their code). I grant you that NVI is a bit different (when I first learned about it, I was shocked to learn that you could override private functions in C++), and I'm not about to claim that that's the way the things should be done in general in D, but I do think that it's a useful idiom and that making private overridable would be useful. And FWIW, TDPL says that it's in the language. - Jonathan M Davis
Oct 04 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 04 Oct 2010 17:54:54 -0400, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Monday, October 04, 2010 13:41:38 Steven Schveighoffer wrote:
 To me, making it private doesn't do anything over protected.  A derived
 class can still call the function in question, because it has the
 implementation.  I don't see what the point is...

 A derived class from the derivative doesn't have access, but it can  
 always
 override it in order to be able to call it (not a good workaround to
 require).

Except that part of the point is that because the private method is private in the base class, it _can't_ be called by derived classes. It can only be overridden.

Sure you can. Altered version of code from one of your articles: #include <set> class Set { std::set<int> s_; public: void add (int i) { s_.insert (i); add_impl (i); // Note virtual call. } void addAll (int * begin, int * end) { s_.insert (begin, end); // --------- (1) addAll_impl (begin, end); // Note virtual call. } private: virtual void add_impl (int i) = 0; virtual void addAll_impl (int * begin, int * end) = 0; }; class CountingSet : public Set { private: int count_; virtual void add_impl (int i) { addAll_impl(&i, (&i) + 1); // hey look, we can call a private method! } virtual void addAll_impl (int * begin, int * end) { count_ += std::distance(begin,end); } }; compiles with g++. So the private restriction does nothing significant IMO. Not responding to the rest of your points, since my argument is predicated on you understanding this first ;) In this example, BTW, I think the significance of private is the fact that the s_ member is private. That *does* prevent derived classes from altering the set except through the common interface. Also, note that I'm not saying NVI isn't a valid or useful pattern (I've used it in the past with success). I just think protected is a better choice for the virtual methods. -Steve
Oct 04 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 05 Oct 2010 03:25:03 -0400, Jacob Carlborg <doob me.com> wrote:

  Who says we need to implement it as g++ does? DMD could implement it to  
 not allow that.

The derived class controls everything. You cannot take control away from the derived class, it just can't be done: class A { private void cantCallMe(); } class B : A { override private void cantCallMe() { butICanCallYou(); } private void butICanCallYou() { /* do impl */ } } so far, private virtual functions == annoyance. I haven't seen anything to prove otherwise yet. -Steve
Oct 05 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 05 Oct 2010 12:07:21 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 10/5/10 7:40 CDT, Steven Schveighoffer wrote:
 On Tue, 05 Oct 2010 03:25:03 -0400, Jacob Carlborg <doob me.com> wrote:

 Who says we need to implement it as g++ does? DMD could implement it
 to not allow that.

The derived class controls everything. You cannot take control away from the derived class, it just can't be done: class A { private void cantCallMe(); } class B : A { override private void cantCallMe() { butICanCallYou(); } private void butICanCallYou() { /* do impl */ } } so far, private virtual functions == annoyance. I haven't seen anything to prove otherwise yet. -Steve

Private overridable functions come with a guarantee that hooks can never be called from an unknown/uncontrolled context.

And when would a protected hook be callable from an unknown/uncontrolled context? In whose eyes, the base or derived class? The thing is, any class that defines a private function implementation is able to call it. You can't prevent that. So in the eyes of any base class, it has no way to restrict that. In the eyes of the derived class, it has no control over whether a base class can call it or not. Essentially a private overridable function has one additional guarantee over a protected function -- a derived class cannot call it if it hasn't defined its own version (and isn't in the same module). But that's not the property desired, the property desired for NVI is that *nobody* can call it except the base class, even derived classes. That's simply not possible. So we have to pretend that we can't call it, which is fine, just as easy with protected. Consider this: abstract class A { public void myAPIFn() { foo(); } abstract private void foo(); } abstract class B : A { public void bar() {myAPIFn();} } class C : B { private void foo() {} } So good so far. But I can alter B so it can circumvent myAPIFn by adding its own implementation for foo (which does nothing), and now I'm able to call foo directly from myAPIFn. Basically, even though B does not intend for its version of foo to be the real implementation (knowing that it's abstract and must be derived), it can hijack A's ability to funnel all calls through myAPIFn by simply adding a blank function. I just don't see the benefit over protected anywhere. You can't say "you're allowed to define this, but you're not allowed to call it." That makes no sense at all, and as I've shown, is impossible to enforce. -Steve
Oct 05 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday 06 October 2010 04:04:24 Steven Schveighoffer wrote:
 On Tue, 05 Oct 2010 20:27:58 -0400, Jonathan M Davis <jmdavisProg gmx.com>
 
 wrote:
 Well, I don't see why it wouldn't be possible for the compiler to
 enforce that
 overridden private methods can't be called by anyone but the base class.
 That
 being the case, then allowing for private virtual functions is most
 definitely
 useful. However, if it really isn't possible to restrict it so that
 derived
 classes can't call the private methods that they've overridden, then I
 do agree
 that we might as well just stick to using protected and make private
 functions
 unoverridable. But if we _can_ make it so that derived classes can't call
 overridden private methods, I think that that would be valuable and
 desirable.

See my earlier post -- if you control the implementation, the compiler cannot prevent you from calling it. Even if it tries... http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&a rticle_id=118350 So you gain nothing, but annoyance (*grumble* now I have to split my implementation from the virtual function just to be able to call it?). -Steve

I do not see why the compiler cannot enforce that a function which overrides another function which is private cannot be called by the derived class even though the implementation is in the derived class. It may not do so now, but I don't see why it couldn't do so. It's already supposed to enforce that the access level of the derived function isn't more restrictive than the base class' function. You'd just make it so that it wouldn't allow it to be called either if the access level were private. - Jonathan M Davis
Oct 06 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 06 Oct 2010 08:23:35 -0400, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Wednesday 06 October 2010 04:04:24 Steven Schveighoffer wrote:
 On Tue, 05 Oct 2010 20:27:58 -0400, Jonathan M Davis  
 <jmdavisProg gmx.com>

 wrote:
 Well, I don't see why it wouldn't be possible for the compiler to
 enforce that
 overridden private methods can't be called by anyone but the base  

 That
 being the case, then allowing for private virtual functions is most
 definitely
 useful. However, if it really isn't possible to restrict it so that
 derived
 classes can't call the private methods that they've overridden, then I
 do agree
 that we might as well just stick to using protected and make private
 functions
 unoverridable. But if we _can_ make it so that derived classes can't  

 overridden private methods, I think that that would be valuable and
 desirable.

See my earlier post -- if you control the implementation, the compiler cannot prevent you from calling it. Even if it tries... http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&a rticle_id=118350 So you gain nothing, but annoyance (*grumble* now I have to split my implementation from the virtual function just to be able to call it?). -Steve

I do not see why the compiler cannot enforce that a function which overrides another function which is private cannot be called by the derived class even though the implementation is in the derived class. It may not do so now, but I don't see why it couldn't do so. It's already supposed to enforce that the access level of the derived function isn't more restrictive than the base class' function. You'd just make it so that it wouldn't allow it to be called either if the access level were private.

You must not have read my prior post. Given this class: class A { abstract private void foo(); } You can construct a class B that *can* call its private implementation, even if the compiler forbids it from calling foo: class B : A { override private void foo() { fooImpl(); } private void fooImpl() {...} } B can call fooImpl whenever it wants, the base class has no fooImpl defined, so the compiler must allow it (unless you want to disallow calling all private functions in derived classes?). This is equivalent to C++'s behavior where you can call any private function you define. -Steve
Oct 06 2010
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, October 06, 2010 05:39:24 Steven Schveighoffer wrote:
 You must not have read my prior post.

Well, I believe that I did read your previous post, but I probably read it too quickly.
 Given this class:
 
 class A
 {
    abstract private void foo();
 }
 
 You can construct a class B that *can* call its private implementation,
 even if the compiler forbids it from calling foo:
 
 class B : A
 {
    override private void foo() { fooImpl(); }
 
    private void fooImpl() {...}
 }
 
 B can call fooImpl whenever it wants, the base class has no fooImpl
 defined, so the compiler must allow it (unless you want to disallow
 calling all private functions in derived classes?).  This is equivalent to
 C++'s behavior where you can call any private function you define.

Hmmm. With mixins and the like it's that much easier to be able to use the same code which is in the private overridden function. So, no, it doesn't look like it would be possible to stop the code that is within the private overridden function from being called, though the function itself couldn't be called. Conceptually, I very much like the idea of making it possible for derived classes to override a private function but not call it, but you make a good argument that it really doesn't buy you much. That being the case, the fact that having private functions be non-virtual is a bit of efficiency gain and allows for easier inlining, it could be that it's just not worth the trouble. You do get most of the benefits of NVI with protected. So, I'm not sure that I like it, but it is looking like using protected for NVI and leaving private as non-virtual may be the way to go. - Jonathan M Davis
Oct 06 2010