March 12, 2014
On 2014-03-12 03:04:38 +0000, Manu <turkeyman@gmail.com> said:

> virtual-by-default is incompatible with optimisation, and it's reliable to
> assume that anybody who doesn't explicitly care about this will stick with
> the default, which means many potentially useful libraries may be
> eliminated for use by many customers.

I'll add another argument to the mix.

Currently, you can't have private/package functions that are virtual, contrary to what TDPL says.

To make things coherent we could change private function so they become virtual by default. You might be able to see the problem with this option: making private function virtual by default is likely to add many performance regressions in existing code, silently.

Or we could implement final by default. This option would instead force people to add 'virtual' here and there, but otherwise existing code is likely to run faster after that.

We could always keep things as they currently are: private/package is not virtual, everything else is virtual unless marked final. Honestly I'd like to se that go. The protection attribute should have nothing to do with whether a function is virtual or not.

-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

March 12, 2014
On Wed, 12 Mar 2014 08:32:14 -0400, Michel Fortin <michel.fortin@michelf.ca> wrote:

> On 2014-03-12 03:04:38 +0000, Manu <turkeyman@gmail.com> said:
>
>> virtual-by-default is incompatible with optimisation, and it's reliable to
>> assume that anybody who doesn't explicitly care about this will stick with
>> the default, which means many potentially useful libraries may be
>> eliminated for use by many customers.
>
> I'll add another argument to the mix.
>
> Currently, you can't have private/package functions that are virtual, contrary to what TDPL says.
>
> To make things coherent we could change private function so they become virtual by default. You might be able to see the problem with this option: making private function virtual by default is likely to add many performance regressions in existing code, silently.

Private virtual functions make 0 sense. A private function cannot be accessed by a derived class. Who gets to access a overriden virtual function? The base class only? If I'm writing a function, I certainly should be able to access it, no? Even if you want to restrict my access, you cannot, I'm in control of that code!

Package, I'm less concerned about. You can make that virtual, I don't ever use package functions.

-Steve
March 12, 2014
On 3/12/14, Michel Fortin <michel.fortin@michelf.ca> wrote:
> Currently, you can't have private/package functions that are virtual, contrary to what TDPL says.

The last word from Walter was that he agreed tying access specifiers to virtuality is wrong, but that it needs a proper DIP.
March 12, 2014
On 2014-03-12 12:48:59 +0000, "Steven Schveighoffer" <schveiguy@yahoo.com> said:

> On Wed, 12 Mar 2014 08:32:14 -0400, Michel Fortin  <michel.fortin@michelf.ca> wrote:
> 
>> I'll add another argument to the mix.
>> 
>> Currently, you can't have private/package functions that are virtual,  contrary to what TDPL says.
>> 
>> To make things coherent we could change private function so they become  virtual by default. You might be able to see the problem with this  option: making private function virtual by default is likely to add many  performance regressions in existing code, silently.
> 
> Private virtual functions make 0 sense. A private function cannot be  accessed by a derived class. Who gets to access a overriden virtual  function? The base class only? If I'm writing a function, I certainly  should be able to access it, no? Even if you want to restrict my access,  you cannot, I'm in control of that code!

You're mixing C++ private with D private. Private just means the symbol is only accessible within the same module. You can have a whole class hierarchy in a module if you want, and thus could override private functions assuming they could be virtual.


-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

March 12, 2014
On 3/12/14, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> Private virtual functions make 0 sense. A private function cannot be accessed by a derived class.

It can if it's in the same module. You may want to have the benefit of virtual functions, but also the benefit of those methods being accessible in some internal API, but not to the user.

If you make them protected, they're accessible by user-derived classes. You could make them package, but currently package is forced non-virtual as well.

> Package, I'm less concerned about. You can make that virtual, I don't ever use package functions.

There is definitely a need for this. DFeed is full of these style of comments:

/+ package +/ /+ protected +/ override int _rtype() // package

It's obviously supposed to be hidden from the user, but it can't be. So underscores are prepended instead.
March 12, 2014
On Wed, 12 Mar 2014 09:15:14 -0400, Michel Fortin <michel.fortin@michelf.ca> wrote:

> On 2014-03-12 12:48:59 +0000, "Steven Schveighoffer" <schveiguy@yahoo.com> said:
>
>> On Wed, 12 Mar 2014 08:32:14 -0400, Michel Fortin  <michel.fortin@michelf.ca> wrote:
>>
>>> I'll add another argument to the mix.
>>>  Currently, you can't have private/package functions that are virtual,  contrary to what TDPL says.
>>>  To make things coherent we could change private function so they become  virtual by default. You might be able to see the problem with this  option: making private function virtual by default is likely to add many  performance regressions in existing code, silently.
>>  Private virtual functions make 0 sense. A private function cannot be  accessed by a derived class. Who gets to access a overriden virtual  function? The base class only? If I'm writing a function, I certainly  should be able to access it, no? Even if you want to restrict my access,  you cannot, I'm in control of that code!
>
> You're mixing C++ private with D private. Private just means the symbol is only accessible within the same module. You can have a whole class hierarchy in a module if you want, and thus could override private functions assuming they could be virtual.

OK, I can see that being useful. You are right, I was thinking C++ private.

So essentially, a virtual private function can only be overridden in classes defined in the same module. What happens when you do it in a separate module, an error? What if you want to define that function name, but it's taken by the base class, what happens?

-Steve
March 12, 2014
On Wednesday, 12 March 2014 at 13:22:34 UTC, Steven Schveighoffer wrote:
> OK, I can see that being useful. You are right, I was thinking C++ private.
>
> -Steve

Even in C++, private virtual a key part of the "non-virtual interface" thing.

EG: You define your base class as having only non-virtual public functions, and private virtual function. They are private, so the derived classes can't *call* them, but they can still override them.

The idea is that the base class holds any "non-modifyable" behavior, and the virtual functions are only "customizeable sub-part behavior".

For example, C++ streams work that way: All the public functions are non-virtual. To create your own streams, you are supposed to only override a set of low level functions, and then the base class takes care of calling them correctly.

In any case, that's how "private virtual" makes sense in C++. I'm less fluent with how it works D classes, but last time I read TDPL, I seem to remember it was built-in in some way.
March 12, 2014
On Wed, 12 Mar 2014 09:45:22 -0400, monarch_dodra <monarchdodra@gmail.com> wrote:

> On Wednesday, 12 March 2014 at 13:22:34 UTC, Steven Schveighoffer wrote:
>> OK, I can see that being useful. You are right, I was thinking C++ private.
>>
>> -Steve
>
> Even in C++, private virtual a key part of the "non-virtual interface" thing.
>
> EG: You define your base class as having only non-virtual public functions, and private virtual function. They are private, so the derived classes can't *call* them, but they can still override them.

Nonsense. If I'm writing a function, I can call it. There is no way to prevent it. e.g.:

class X
{
   virtual void _foo() {/* default impl */}
public:
   void foo() {_foo();}
}

class Y : public X
{
   virtual void _foo() {_foo2();}
   void _foo2() { /* do whatever I want here */}
}

OK, so your idea is that I can't call my copy of _foo, which if that's how it works, is dumb in my opinion. But if that's the case, I'm in control of its implementation, I can just forward to another function that I can call.

> The idea is that the base class holds any "non-modifyable" behavior, and the virtual functions are only "customizeable sub-part behavior".
>
> For example, C++ streams work that way: All the public functions are non-virtual. To create your own streams, you are supposed to only override a set of low level functions, and then the base class takes care of calling them correctly.

The idea is fine, but protected serves this purpose just as well.

-Steve
March 12, 2014
On 3/12/14, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> The idea is fine, but protected serves this purpose just as well.

Protected still allows subclasses to *call* the methods. The idea is that the base class provides a public API which implements the calling, because only it knows in which order some private functions should be called.
March 12, 2014
On Wednesday, 12 March 2014 at 12:48:58 UTC, Steven Schveighoffer wrote:
> On Wed, 12 Mar 2014 08:32:14 -0400, Michel Fortin <michel.fortin@michelf.ca> wrote:
>
>> On 2014-03-12 03:04:38 +0000, Manu <turkeyman@gmail.com> said:
>>
>>> virtual-by-default is incompatible with optimisation, and it's reliable to
>>> assume that anybody who doesn't explicitly care about this will stick with
>>> the default, which means many potentially useful libraries may be
>>> eliminated for use by many customers.
>>
>> I'll add another argument to the mix.
>>
>> Currently, you can't have private/package functions that are virtual, contrary to what TDPL says.
>>
>> To make things coherent we could change private function so they become virtual by default. You might be able to see the problem with this option: making private function virtual by default is likely to add many performance regressions in existing code, silently.
>
> Private virtual functions make 0 sense. A private function cannot be accessed by a derived class. Who gets to access a overriden virtual function? The base class only? If I'm writing a function, I certainly should be able to access it, no? Even if you want to restrict my access, you cannot, I'm in control of that code!
>
> Package, I'm less concerned about. You can make that virtual, I don't ever use package functions.
>
> -Steve

Private virtual functions actually make a LOT of sense in C++. Ever heard of NVI? It is actually good design practice to make class virtuals private in many cases and relay on Template Method pattern. Even Andrei advices that in C++ Coding Standards.