On 31 May 2013 14:06, deadalnix <deadalnix@gmail.com> wrote:
On Friday, 31 May 2013 at 02:56:25 UTC, Andrei Alexandrescu wrote:
On 5/30/13 9:26 PM, finalpatch wrote:
https://dl.dropboxusercontent.com/u/974356/raytracer.d
https://dl.dropboxusercontent.com/u/974356/raytracer.cpp

Manu's gonna love this one: make all methods final.


I don't think going as far as making thing final by default make sense at this point. But we sure need a way to be able to finalize methods. We had an extensive discussion with Don and Manu at DConf, here are some idea that came out :

 - Final by default

This one is really a plus when it come to performance code. However, virtual by default have proven itself very useful when performance isn't that big of a deal (and it is the case for 90% of a program's code usually) and limiting the usage of some pattern like decorator (that also have been proven to be useful). This is also  huge breakage.

The correct choice :)

> virtual by default have proven itself very useful when performance isn't that big of a deal

Has it? I'm not sure it's ever proven its self useful, can you point to any such proof, or evidence?
I think it's only *proven* its self to be a massive mistake; you've all heard my arguments a million times, Don will also give a massive rant, and others.

People already have to type 'override' in every derived class, and they're happy to do that. Requiring to type 'virtual' in the base is hardly an inconvenience by contrast. Actually, it's quite orthogonal.
D tends to prefer being explicit. Why bend the rules in this case, especially considering the counterpart (override) is expected to be explicit? Surely both being explicit is what people would expect?

There's another detail that came up late at night at dconf; I was talking to Daniel Murphy about the extern(C++) class work he's working on to write the D-DMD front end, and apparently it would make the problem a lot easier if virtual was explicit there too. So perhaps it also offers improved interoperability with C++, which I think most of us have agreed is of heightened importance recently.

> and it is the case for 90% of a program's code usually

Can you justify this? I believe it's more like 5% of methods, or less.
In my experience, virtuals account for 1-2 functions, and trivial properties (which should avoid being virtual at all costs) account for almost all of them.

int getPrivateMember() { return privateMember; } // <- most methods are like this; should NEVER be virtual

> This is also  huge breakage.

I think this is another fallacy. The magnitude of the breakage is already known. It's comparable to the recent change where 'override' became an explicit requirement, which was hardly catastrophic.
In that case, the breakage occurred in *every derived class*, which is a many:1 relationship to base classes.
Explicit virtual would only affect _base_ classes. The magnitude of which is far smaller than what was recently considered acceptable, precisely: magnitudeOfPriorBreakage / numberOfDerivedClasses.

So considering explicit override was an argument won, I'd like to think that explicit virtual deserves the same treatment for even more compelling reasons, and at a significantly lesser cost in breakage.

 - Introduce a virtual keyword.

Virtual by default isn't such a big deal if you can do final: and reverse the default behavior. However, once you key in the final land, you are trapped here, you can't get out. Introducing a virtual keyword would allow for aggressive final: declarations.

This needs to be done either way.

 - Require explicitly export when you want to create shared objects.

This one is an enabler for an optimizer to finalize virtual method. With this mechanism in place, the compile knows all the override and can finalize many calls during LTO. I especially like that one as it allow for stripping many symbols at link time and allow for other LTO in general (for instance, the compiler can choose custom calling conventions for some methods, knowing all call sites).

The explicit export one have my preference, however, ti require that symbol used in shared lib are explicitly declared export. I think we shouldn't break the virtual by default behavior, but we still need to figure out a way to make thing more performant on this point.

You're concerned about the magnitude of breakage introducing an explicit virtual requirement. This would seem to be a much much bigger breakage to me, and I don't think it's intuitive.