June 06, 2013
On Thursday, 6 June 2013 at 15:06:38 UTC, Kapps wrote:
> Java for example uses frameworks such as Mockito to allow you to mock final methods (and static methods as well); the virtual by default doesn't change that.

Sorry, that should be PowerMock not Mockito.
June 06, 2013
On Tuesday, 4 June 2013 at 00:19:39 UTC, Manu wrote:
> Is there a reason this change offends you enough to call me names? Or can
> you at least tell how I'm being narrow-minded?

It's not at all the change itself that irritates me. I would never resort to making ad hominem arguments in a technical discussion, at least not deliberately so.

In fact, from what I remember from the various discussions at DConf, I think we have pretty much the same opinion regarding how hidden costs are a bit too pervasive in present-day D, respectively how it encourages an inherently wasteful style of coding in more places than necessary. I also agree that in the current class design, virtual-by-default is dangerous. If we were to go back to the drawing board, though, I'd be interested in exploring alternative directions in the design space, away from the Java-style OOP model altogether.

What I disagree with is just the style of the discussion, for reasons that Andrei already summarized in a much more eloquent way than I could. Trying to Be Right on the Internet is one thing, but does not necessarily improve the situation at all. And even if they eventually do, such discussions tend to be a much bigger waste of time and energy for everybody involved than necessary, which is also the reason why I mostly ignored this thread so far.

David
June 06, 2013
On 06/06/2013 05:00 PM, Steven Schveighoffer wrote:
> On Wed, 05 Jun 2013 21:14:08 -0400, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
>> I would have expected something more like
>>
>> 1. 'virtual' means a method is an "introducing" one.
>> 2. 'override' means override with a non-final function.
>> 3. 'final override' means a method overrides a base virtual function with a
>> final function.
>> 4. 'final' by itself both mean final and non-overriding.
> 
> I agree, I think it can be expressed by answering two questions:
> 
> 1. Do you want to participate in a base class' virtual call
> 2. Do you want to allow derived classes to participate in the virtual call.
> 
> If you answer yes to 1, add override, otherwise (or if there is no base method),
> add nothing (in C# answering no, you should add 'new' if there is an existing
> base function)
> If you answer yes to 2, add virtual, otherwise, add final.

I see a potential problem with allowing 'final' on its own to mean 'final and non-overriding', which is that if you _mean_ to override a function in the base class, but put simply 'final' and not 'override', it will still be accepted by the compiler -- and it may not be obvious that the override is not taking place.

So, I think 'new' could have a place here after all.
June 06, 2013
On Thursday, 6 June 2013 at 15:40:26 UTC, Joseph Rushton Wakeling wrote:

> I see a potential problem with allowing 'final' on its own to mean 'final and
> non-overriding', which is that if you _mean_ to override a function in the base
> class, but put simply 'final' and not 'override', it will still be accepted by
> the compiler -- and it may not be obvious that the override is not taking place.
>
> So, I think 'new' could have a place here after all.

My understanding is that final on it's own would be an error if the same named function was virtual in the base class, otherwise you would have to specify "final override". If that understanding is not correct, then I agree that would be a source of hidden errors.

--rt
June 06, 2013
On Thu, 06 Jun 2013 11:40:18 -0400, Joseph Rushton Wakeling <joseph.wakeling@webdrake.net> wrote:

> On 06/06/2013 05:00 PM, Steven Schveighoffer wrote:
>> On Wed, 05 Jun 2013 21:14:08 -0400, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
>>> I would have expected something more like
>>>
>>> 1. 'virtual' means a method is an "introducing" one.
>>> 2. 'override' means override with a non-final function.
>>> 3. 'final override' means a method overrides a base virtual function with a
>>> final function.
>>> 4. 'final' by itself both mean final and non-overriding.
>>
>> I agree, I think it can be expressed by answering two questions:
>>
>> 1. Do you want to participate in a base class' virtual call
>> 2. Do you want to allow derived classes to participate in the virtual call.
>>
>> If you answer yes to 1, add override, otherwise (or if there is no base method),
>> add nothing (in C# answering no, you should add 'new' if there is an existing
>> base function)
>> If you answer yes to 2, add virtual, otherwise, add final.
>
> I see a potential problem with allowing 'final' on its own to mean 'final and
> non-overriding', which is that if you _mean_ to override a function in the base
> class, but put simply 'final' and not 'override', it will still be accepted by
> the compiler -- and it may not be obvious that the override is not taking place.

Yes, this is a departure from the current code, which doesn't allow this.

But it is a generalized problem, not specific to final.  It's basically the lack of a storage class for meaning "no, I don't want to override the function".  Note that final does NOT do this.  In fact, we don't have a way to do this now.

new could be that storage class, but I am cautious about it.  new has a position close to that context, for custom allocators.

Another storage class would complete the solution, and make intentions very easy to make obvious.  At that point, we could have a warning/error for under-specification.

And another note to make is that the case where you are 'hiding' a base final function isn't really a problem.  It's more when you are hiding a virtual function, that this becomes an issue.  More likely, when you are hiding a *new* virtual function, because it didn't exist when you wrote your code.

-Steve
June 06, 2013
On Wednesday, June 05, 2013 22:50:14 Michel Fortin wrote:
> P.S.: while implementing this change, please make sure private and package functions can be virtual.

I'd agree with package on that, but I don't think that private should be virtualizable, because that conflicts with actually hiding non-accessible functions, which is what a number of us are pushing for. Otherwise, private implementation details of classes and modules risk causing code breakage (e.g. the fact that overload resolution occurs before checking the access level is atrocious).

- Jonathan M Davis
June 06, 2013
On Thursday, 6 June 2013 at 15:33:19 UTC, David Nadlinger wrote:
> In fact, from what I remember from the various discussions at DConf, I think we have pretty much the same opinion regarding how hidden costs are a bit too pervasive in present-day D, respectively how it encourages an inherently wasteful style of coding in more places than necessary. I also agree that in the current class design, virtual-by-default is dangerous. If we were to go back to the drawing board, though, I'd be interested in exploring alternative directions in the design space, away from the Java-style OOP model altogether.
>

scala's is pretty much the definition of awesome on that one. If it had to be redone, I'd push in that direction.
June 06, 2013
On Thursday, 6 June 2013 at 15:06:38 UTC, Kapps wrote:
> On Thursday, 6 June 2013 at 01:08:36 UTC, deadalnix wrote:
>> This is why I wrote that this may have been true in the past. Nevertheless, it is completely false today.
>
> C# often does not inline virtual methods, and even if it can inline them there's still an overhead. This (2008) article goes into depth about how it handles it: www.codeproject.com/Articles/25801/JIT-Optimizations - Essentially uses frequency analysis to determine if the virtual method call is still going to call the same method as it would previously. Regardless, we can not perform such optimizations, so whether or not it applies to C#, it does apply to D.
>

Quite frankly, I don't care what C# does. Java does it at link time, and we can do it at link time the same way, that is all that matter for this discussion.

Unless C# don't do it because it is impossible, this is only a C# implementation detail.
June 06, 2013
On Thu, 06 Jun 2013 13:50:11 -0400, deadalnix <deadalnix@gmail.com> wrote:

> On Thursday, 6 June 2013 at 15:06:38 UTC, Kapps wrote:
>> On Thursday, 6 June 2013 at 01:08:36 UTC, deadalnix wrote:
>>> This is why I wrote that this may have been true in the past. Nevertheless, it is completely false today.
>>
>> C# often does not inline virtual methods, and even if it can inline them there's still an overhead. This (2008) article goes into depth about how it handles it: www.codeproject.com/Articles/25801/JIT-Optimizations - Essentially uses frequency analysis to determine if the virtual method call is still going to call the same method as it would previously. Regardless, we can not perform such optimizations, so whether or not it applies to C#, it does apply to D.
>>
>
> Quite frankly, I don't care what C# does. Java does it at link time, and we can do it at link time the same way, that is all that matter for this discussion.

How do you finalize a method with the possibility that a dynamic library will come along and extend that type?  Not a rhetorical question, I really want to know if there is a way.  Java and C# clearly have more flexibility there, since they are run on a VM.

-Steve
June 06, 2013
On Thursday, 6 June 2013 at 17:56:05 UTC, Steven Schveighoffer wrote:
> How do you finalize a method with the possibility that a dynamic library will come along and extend that type?  Not a rhetorical question, I really want to know if there is a way.  Java and C# clearly have more flexibility there, since they are run on a VM.
>

We are turning around here. You can't.

But it doesn't really matter as the call is already opaque and so it is slow. The impact isn't that big relatively (consider in the code above it was 5% on a statically compiled code).

It is also possible to automatically generate code like :
if (virtualMethod == givenMethod) {
    givenMethod();
} else {
    virtualMethod();
}

It sound like it is completely stupid, but in fact, as the compiler know the call you'll do, it can run optimizations.

But I want to repeat myself once again : trying to fix virtual call to shared object isn't gone change much in regard of performances.