March 18, 2012
F i L:

> I'm a bit confused. Reading through the virtual function's docs (http://dlang.org/function.html#virtual-functions) it says:
> 
> "All non-static non-private non-template member functions are virtual. This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual."

This is so much theoretical that I think this should be removed from the D docs. And to be put back when one DMD compiler is able to do this. Otherwise it's just false advertising :-)

Bye,
bearophile
March 18, 2012
On Sunday, 18 March 2012 at 03:27:40 UTC, bearophile wrote:
> F i L:
>
>> I'm a bit confused. Reading through the virtual function's docs (http://dlang.org/function.html#virtual-functions) it says:
>> 
>> "All non-static non-private non-template member functions are virtual. This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual."
>
> This is so much theoretical that I think this should be removed from the D docs. And to be put back when one DMD compiler is able to do this. Otherwise it's just false advertising :-)
>
> Bye,
> bearophile

Dammit, I was afraid someone would say something like that. Well at least it's a good goal. It is a bit of false advertising though, honestly it should just be marked "implementation in progress" or something like that.

March 18, 2012
On 3/17/12 9:24 PM, Manu wrote:
> Yeah, I'm not really into that. I group things conceptually.
> Either way, I've never written a class where non-virtuals don't outweigh
> virtuals in the realm of 20:1.

Then probably struct is what you're looking for.

Andrei
March 18, 2012
On 3/18/2012 12:27 PM, bearophile wrote:
> F i L:
>
>> I'm a bit confused. Reading through the virtual function's docs
>> (http://dlang.org/function.html#virtual-functions) it says:
>>
>> "All non-static non-private non-template member functions are
>> virtual. This may sound inefficient, but since the D compiler
>> knows all of the class hierarchy when generating code, all
>> functions that are not overridden can be optimized to be
>> non-virtual."
>
> This is so much theoretical that I think this should be removed from the D docs. And to be put back when one DMD compiler is able to do this. Otherwise it's just false advertising :-)
>
> Bye,
> bearophile

It says "can be optimized", not "are optimized". Big difference.
March 18, 2012
On Sunday, 18 March 2012 at 03:27:40 UTC, bearophile wrote:
> F i L:
>> "All non-static non-private non-template member functions are virtual. This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual."
>
> This is so much theoretical that I think this should be removed from the D docs. And to be put back when one DMD compiler is able to do this. Otherwise it's just false advertising :-)

Is this even possible without LTO/WPO? Extending a class defined in a library you link in (and for which codegen already happened) is certainly possible…

David
March 18, 2012
On 18 March 2012 04:47, F i L <witte2008@gmail.com> wrote:

> I'm a bit confused. Reading through the virtual function's docs ( http://dlang.org/function.**html#virtual-functions<http://dlang.org/function.html#virtual-functions>) it says:
>
> "All non-static non-private non-template member functions are virtual. This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual."
>
> So if all functions are automatically optimized to non-virtual where applicable, then the "final" keyword is for conceptual access limitation only. This makes a lot of sense to me. Is there something I'm not getting that makes you want an explicit "virtual" keyword?
>

It's not dependable. Virtually everything meets those criteria and will be
virtual, but I want to be confident that NOTHING is EVER virtual, unless I
absolutely say so.
D knows nothing about the class hierarchy when generating code, I don't
know how it can make that claim? Anything that's not private can be
extended by another module, and only the linker could ever know out about
that.
Aside from that, I want a compile error if someone tries to randomly
override stuff. virtuals are a heinous crime, and should only be used
explicitly. It should not be possible for someone to accidentally create a
virtual.


March 18, 2012
On 18 March 2012 06:42, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>
 wrote:

> On 3/17/12 9:24 PM, Manu wrote:
>
>> Yeah, I'm not really into that. I group things conceptually.
>> Either way, I've never written a class where non-virtuals don't outweigh
>> virtuals in the realm of 20:1.
>>
>
> Then probably struct is what you're looking for.


No, I definitely want a class. ref type, gc mem, etc.
struct doesn't support virtual at all. I have 2 virtuals, this particular
class has around 50 public methods, almost all of which are trivial
accessors, called extremely heavily in hot loops. More similar classes to
come.

I've never in 15 years seen a large-ish class where the majority of methods
are virtual. Who writes code like that? It's never come up in my industry
at least.
Maybe you'll occasionally see it in a small interface class, but D has real
interfaces...


On 18 March 2012 11:00, David Nadlinger <see@klickverbot.at> wrote:

> Is this even possible without LTO/WPO? Extending a class defined in a library you link in (and for which codegen already happened) is certainly possible…
>

It's not possible without LTO, which is crazy. Depending on an advanced optimiser to generate the most basic code is a clear mistake.

I think we just need the ability to state 'final:' and mark explicit 'virtual's, the problem is mitigated without breaking the language. I can live with a policy where everyone is instructed to write code that way.


March 18, 2012
On 2012-03-18 04:27, bearophile wrote:
> F i L:
>
>> I'm a bit confused. Reading through the virtual function's docs
>> (http://dlang.org/function.html#virtual-functions) it says:
>>
>> "All non-static non-private non-template member functions are
>> virtual. This may sound inefficient, but since the D compiler
>> knows all of the class hierarchy when generating code, all
>> functions that are not overridden can be optimized to be
>> non-virtual."
>
> This is so much theoretical that I think this should be removed from the D docs. And to be put back when one DMD compiler is able to do this. Otherwise it's just false advertising :-)

I agree that can be misleading. But I think the D docs should be about the D language and not DMD implementation of D.

-- 
/Jacob Carlborg
March 18, 2012
Manu wrote:
> D knows nothing about the class hierarchy when generating code, I don't know how it can make that claim?

How does D not know about class hierarchy when generating code? That doesn't make sense to me. It *has* to know to even generate code.

> Anything that's not private can be
> extended by another module, and only the linker could ever know out about that.

This shouldn't be an issue:

export void method() // virtual
export final void method() // non-virtual

> Aside from that, I want a compile error if someone tries to randomly override stuff.

This only really applies if the compiler can't optimize virtuals away. If the compiler was very good, then getting compiler errors would only make extending object structure a pain, IMO. I can see how one programmer might accidentally create a function with the same name as the base classes name, and how that would be annoying. That's why...

> virtuals are a heinous crime, and should only be used
> explicitly. It should not be possible for someone to accidentally create a virtual.

...I don't think having a virtual keyword would be a bad thing. Still, I think conceptually saying "you _can't_ override this" makes more sense than saying "you _can_ override this" when the biggest reason for using Classes is to build extendable object types.

I think at the end of the day both arguments are highly arbitrary. virtual and final keywords could probably exist peacefully, and wouldn't dent the learning curve by much, so I don't have any strong argument against virtual. It's just not the one I'd choose.


March 18, 2012
On 18 March 2012 13:59, F i L <witte2008@gmail.com> wrote:

> Manu wrote:
>
>> D knows nothing about the class hierarchy when generating code, I don't know how it can make that claim?
>>
>
> How does D not know about class hierarchy when generating code? That doesn't make sense to me. It *has* to know to even generate code.


I mean it can't possibly know the complete 'final' class hierarchy, ie, the big picture. Anything anywhere could extend it. The codegen must assume such.


> Aside from that, I want a compile error if someone tries to randomly
>> override stuff.
>>
>
> This only really applies if the compiler can't optimize virtuals away. If the compiler was very good, then getting compiler errors would only make extending object structure a pain, IMO. I can see how one programmer might accidentally create a function with the same name as the base classes name, and how that would be annoying. That's why...


Are you saying someone might accidentally override something that's not virtual? That's what 'override' is for. If a method is final, it is a compile error to override in any way, you either need to make the base virtual, or explicitly 'override' on the spot if you want to do that.


> virtuals are a heinous crime, and should only be used
>> explicitly. It should not be possible for someone to accidentally create a virtual.
>>
>
> ...I don't think having a virtual keyword would be a bad thing. Still, I think conceptually saying "you _can't_ override this" makes more sense than saying "you _can_ override this" when the biggest reason for using Classes is to build extendable object types.
>

I see it precisely the other way around. You still need strict control over
precisely HOW to extend that thing. The virtual methods are the exception,
not the common case. Explicit virtual even gives a nice informative cue to
the programmer just how they are supposed to work with/extend something.
You can clearly see what can/should to be extended.
Add to that the requirement for an advanced optimiser to clean up the mess
with LTO, and the fact a programmer can never have confidence in the final
state of the function, I want it the other way around.
I sincerely fear finding myself false-virtual hunting on build night until
2am trying to get the game to hold its frame rate (I already do this in
C++, but at least you can grep for and validate them!). Or cutting content
because we didn't take the time required to manually scan for false
virtuals that could have given us more frame time.

I think at the end of the day both arguments are highly arbitrary. virtual
> and final keywords could probably exist peacefully, and wouldn't dent the learning curve by much, so I don't have any strong argument against virtual. It's just not the one I'd choose.
>

You're welcome to it, but granted that, I have an additional fear that someone with your opinion is capable of writing classes in libs that I might really like to use, but can't, because they are a severe performance hazard. It will be a shame if there is eventually a wealth of D libraries, and only some of them are usable in realtime code because the majority of programmers are blind to this problem. (Again, this is also common in C++. I've encountered many libraries over the years that we had to reject, or even more costly, remove later on after integrating and realising they were unusable)