www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - private is non-virtual: Stuck in C++-thinking?

reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
My understanding is that this is intentionally disallowed:

---------------------------
module foo;

class Foo
{
    private void func() {}
}

class Bar : Foo
{
    // Disallowed:
    private override void func() {}
}

void foobar(Foo f)
{
    f.func();
}
---------------------------

If D had C++'s "private", that restriction would make a lot of sense
(except possibly for nested classes, but I dunno). That's because: How
can you override a class you can't even access?

But D doesn't have a "true" private in the C++ sense. Instead, there
is code outside a class which *is* permitted to access "private"
members.

So am I missing something, or was the sample case above overlooked when
making the "private must be non-virtual" decision?
Oct 19 2012
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 19 October 2012 at 21:09:05 UTC, Nick Sabalausky wrote:
 My understanding is that this is intentionally disallowed:

 ---------------------------
 module foo;

 class Foo
 {
     private void func() {}
 }

 class Bar : Foo
 {
     // Disallowed:
     private override void func() {}
 }

 void foobar(Foo f)
 {
     f.func();
 }
 ---------------------------

 If D had C++'s "private", that restriction would make a lot of 
 sense
 (except possibly for nested classes, but I dunno). That's 
 because: How
 can you override a class you can't even access?

 But D doesn't have a "true" private in the C++ sense. Instead, 
 there
 is code outside a class which *is* permitted to access "private"
 members.

 So am I missing something, or was the sample case above 
 overlooked when
 making the "private must be non-virtual" decision?

According to TDPL, this should be legal. In particular, there is an entire section about it regarding NVI. No idea what it going on, but I'm curious for answers.
Oct 19 2012
parent deadalnix <deadalnix gmail.com> writes:
Le 20/10/2012 01:14, Jonathan M Davis a écrit :
 On Friday, October 19, 2012 23:22:26 monarch_dodra wrote:
 According to TDPL, this should be legal. In particular, there is
 an entire section about it regarding NVI.

 No idea what it going on, but I'm curious for answers.

For interfaces, where it's doing something to specifically enable NVI. It never says that for classes. It's been discussed a number of times before, and I think that it's fairly clear that Walter has no intention of changing it. Regardless, it would actually be a _huge_ problem for private to be virtual, and it's completely unnecessary for NVI (protected does the job just fine). If private were virtual, then it that would kill inlining and any other optimization relying on knowing the body of the function or anything else which gets affected by a function being virtual - including the cost of the vtable lookup.

Yes, if you don't want that, just define this a a private free function. D isn't some kind of language where everything need to be an object.
Oct 23 2012
prev sibling next sibling parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Friday, 19 October 2012 at 21:22:28 UTC, monarch_dodra wrote:
 On Friday, 19 October 2012 at 21:09:05 UTC, Nick Sabalausky
 So am I missing something, or was the sample case above 
 overlooked when
 making the "private must be non-virtual" decision?

According to TDPL, this should be legal. In particular, there is an entire section about it regarding NVI. No idea what it going on, but I'm curious for answers.

It's a bug. http://d.puremagic.com/issues/show_bug.cgi?id=3581 http://d.puremagic.com/issues/show_bug.cgi?id=4542
Oct 19 2012
prev sibling next sibling parent reply "foobar" <foo bar.com> writes:
On Friday, 19 October 2012 at 21:09:05 UTC, Nick Sabalausky wrote:
 My understanding is that this is intentionally disallowed:

 ---------------------------
 module foo;

 class Foo
 {
     private void func() {}
 }

 class Bar : Foo
 {
     // Disallowed:
     private override void func() {}
 }

 void foobar(Foo f)
 {
     f.func();
 }
 ---------------------------

 If D had C++'s "private", that restriction would make a lot of 
 sense
 (except possibly for nested classes, but I dunno). That's 
 because: How
 can you override a class you can't even access?

 But D doesn't have a "true" private in the C++ sense. Instead, 
 there
 is code outside a class which *is* permitted to access "private"
 members.

 So am I missing something, or was the sample case above 
 overlooked when
 making the "private must be non-virtual" decision?

virtual private is an obscure C++ idiom which I think the argument for is extremely week. I think Walter made the right decision here in favor of more readable code. I'd do the following: --------------------------- module foo; class Foo { private void func() { funcImpl(); } protected void funcImpl() {} } class Bar : Foo { protected override void funcImpl() {} } void foobar(Foo f) { f.func(); } ---------------------------
Oct 19 2012
parent deadalnix <deadalnix gmail.com> writes:
Le 20/10/2012 00:18, foobar a écrit :
 On Friday, 19 October 2012 at 21:09:05 UTC, Nick Sabalausky wrote:
 My understanding is that this is intentionally disallowed:

 ---------------------------
 module foo;

 class Foo
 {
 private void func() {}
 }

 class Bar : Foo
 {
 // Disallowed:
 private override void func() {}
 }

 void foobar(Foo f)
 {
 f.func();
 }
 ---------------------------

 If D had C++'s "private", that restriction would make a lot of sense
 (except possibly for nested classes, but I dunno). That's because: How
 can you override a class you can't even access?

 But D doesn't have a "true" private in the C++ sense. Instead, there
 is code outside a class which *is* permitted to access "private"
 members.

 So am I missing something, or was the sample case above overlooked when
 making the "private must be non-virtual" decision?

virtual private is an obscure C++ idiom which I think the argument for is extremely week. I think Walter made the right decision here in favor of more readable code. I'd do the following: --------------------------- module foo; class Foo { private void func() { funcImpl(); } protected void funcImpl() {} } class Bar : Foo { protected override void funcImpl() {} } void foobar(Foo f) { f.func(); } ---------------------------

Being able to define function but prevent from calling them is a very usefull thing. Especially when you want to allow to redefine behavior that would let the object in an invalid state.
Oct 23 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, October 19, 2012 23:22:26 monarch_dodra wrote:
 According to TDPL, this should be legal. In particular, there is
 an entire section about it regarding NVI.
 
 No idea what it going on, but I'm curious for answers.

For interfaces, where it's doing something to specifically enable NVI. It never says that for classes. It's been discussed a number of times before, and I think that it's fairly clear that Walter has no intention of changing it. Regardless, it would actually be a _huge_ problem for private to be virtual, and it's completely unnecessary for NVI (protected does the job just fine). If private were virtual, then it that would kill inlining and any other optimization relying on knowing the body of the function or anything else which gets affected by a function being virtual - including the cost of the vtable lookup. You would be forced to mark all private functions as final to fix this, which most people won't do, which would lead to performance hits everywhere where classes are used. Classes in D would be less performant for essentially _zero_ gain. If you want virtual but don't want the function to be public, then use protected. - Jonathan M Davis
Oct 19 2012
prev sibling next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Sat, 20 Oct 2012 00:18:28 +0200
"foobar" <foo bar.com> wrote:
 
 virtual private is an obscure C++ idiom which I think the 
 argument for is extremely week.

Well like I said though, virtual private is *very* different in C++ than it is in D, because private itself is very different in C++ than in D.
 I think Walter made the right 
 decision here in favor of more readable code.
 

Oct 19 2012
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 19 October 2012 at 22:18:29 UTC, foobar wrote:
 virtual private is an obscure C++ idiom which I think the 
 argument for is extremely week. I think Walter made the right 
 decision here in favor of more readable code.

Really? it is the entire point of NVI. I've seen it used all the time. It is even used (and documented) in the STL, as the way to customize streams... On Friday, 19 October 2012 at 23:14:32 UTC, Jonathan M Davis wrote:
 On Friday, October 19, 2012 23:22:26 monarch_dodra wrote:
 According to TDPL, this should be legal. In particular, there 
 is
 an entire section about it regarding NVI.
 
 No idea what it going on, but I'm curious for answers.

For interfaces, where it's doing something to specifically enable NVI. It never says that for classes.

Good point. I've not much experience with interfaces yet, so the difference didn't strike at me. Yeah, once you define an interface, I guess the point of virtual private-ness becomes moot.
Oct 20 2012
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, October 23, 2012 21:34:35 deadalnix wrote:
 Le 20/10/2012 01:14, Jonathan M Davis a écrit :
 On Friday, October 19, 2012 23:22:26 monarch_dodra wrote:
 According to TDPL, this should be legal. In particular, there is
 an entire section about it regarding NVI.
 
 No idea what it going on, but I'm curious for answers.

For interfaces, where it's doing something to specifically enable NVI. It never says that for classes. It's been discussed a number of times before, and I think that it's fairly clear that Walter has no intention of changing it. Regardless, it would actually be a _huge_ problem for private to be virtual, and it's completely unnecessary for NVI (protected does the job just fine). If private were virtual, then it that would kill inlining and any other optimization relying on knowing the body of the function or anything else which gets affected by a function being virtual - including the cost of the vtable lookup.

Yes, if you don't want that, just define this a a private free function. D isn't some kind of language where everything need to be an object.

That's no better than expecting programmers to mark all of their private functions final. It's not what they'll do normally, so they'll end up with slower code and complain about it. It just makes things slow by default, and being able to override private functions gains you pretty much _nothing_. _All_ that it does is make it impossible to call the base class implementation of the function. You can still call the implementation in the derived class. protected will do _exactly_ the same thing for you except that derived classes will be able to call the base class implementation rather than just their own. Making it impossible to call the base class implementation isn't even vaguely worth the performance costs that then affects almost every class ever written in D. - Jonathan M Davis
Oct 23 2012