March 13, 2014
On Thursday, 13 March 2014 at 19:38:20 UTC, Dmitry Olshansky wrote:
> 13-Mar-2014 21:52, monarch_dodra пишет:
>> So maybe the issue could be solved by educating to always type (by
>> default):
>>
>> final class A
>> {...}
>
> Not the same as `final:` inside - the above just means you can't inherit from A. Funnily enough any new methods in A would still be virtual even if nothing can inherit from it!

What!? That's... horrible! What's the point of that? Is there *any* situation where that makes sense?
March 13, 2014
On Thursday, 13 March 2014 at 19:38:20 UTC, Dmitry Olshansky wrote:
> Not the same as `final:` inside - the above just means you can't inherit from A. Funnily enough any new methods in A would still be virtual even if nothing can inherit from it!

This should have been fixed years ago:
https://d.puremagic.com/issues/show_bug.cgi?id=2326

Is it a regression?
March 13, 2014
14-Mar-2014 00:24, Vladimir Panteleev пишет:
> On Thursday, 13 March 2014 at 19:38:20 UTC, Dmitry Olshansky wrote:
>> Not the same as `final:` inside - the above just means you can't
>> inherit from A. Funnily enough any new methods in A would still be
>> virtual even if nothing can inherit from it!
>
> This should have been fixed years ago:
> https://d.puremagic.com/issues/show_bug.cgi?id=2326
>
> Is it a regression?

I stand corrected. I double checked and indeed compiler produces direct calls.


-- 
Dmitry Olshansky
March 13, 2014
On Thursday, 13 March 2014 at 20:42:15 UTC, Dmitry Olshansky wrote:
> 14-Mar-2014 00:24, Vladimir Panteleev пишет:
>> On Thursday, 13 March 2014 at 19:38:20 UTC, Dmitry Olshansky wrote:
>>> Not the same as `final:` inside - the above just means you can't
>>> inherit from A. Funnily enough any new methods in A would still be
>>> virtual even if nothing can inherit from it!
>>
>> This should have been fixed years ago:
>> https://d.puremagic.com/issues/show_bug.cgi?id=2326
>>
>> Is it a regression?
>
> I stand corrected. I double checked and indeed compiler produces direct calls.

Whew!
March 13, 2014
On 3/13/14, 1:42 PM, Dmitry Olshansky wrote:
> 14-Mar-2014 00:24, Vladimir Panteleev пишет:
>> On Thursday, 13 March 2014 at 19:38:20 UTC, Dmitry Olshansky wrote:
>>> Not the same as `final:` inside - the above just means you can't
>>> inherit from A. Funnily enough any new methods in A would still be
>>> virtual even if nothing can inherit from it!
>>
>> This should have been fixed years ago:
>> https://d.puremagic.com/issues/show_bug.cgi?id=2326
>>
>> Is it a regression?
>
> I stand corrected. I double checked and indeed compiler produces direct
> calls.

My other question stands :o).

Andrei

March 13, 2014
On Thursday, 13 March 2014 at 20:21:51 UTC, monarch_dodra wrote:
> On Thursday, 13 March 2014 at 19:38:20 UTC, Dmitry Olshansky wrote:
>> 13-Mar-2014 21:52, monarch_dodra пишет:
>>> So maybe the issue could be solved by educating to always type (by
>>> default):
>>>
>>> final class A
>>> {...}
>>
>> Not the same as `final:` inside - the above just means you can't inherit from A. Funnily enough any new methods in A would still be virtual even if nothing can inherit from it!
>
> What!? That's... horrible! What's the point of that? Is there *any* situation where that makes sense?

That is certainly a compiler bug if this is the case.
March 13, 2014
On 3/13/2014 1:16 AM, Andrej Mitrovic wrote:
> On 3/13/14, Walter Bright <newshound2@digitalmars.com> wrote:
>> I didn't even know about this client before the breakage.
>
> I'm really getting tired of this argument. An unknown client (which
> you still haven't named,

Companies won't trust me if whatever they say about their private business I blather over the internet. My default behavior is, unless they give me explicit permission, to treat my interactions with them as confidential.


> so as far as I'm concerned it might as well
> be just a reddit troll) comes out of the blue,

I find this accusation quite unfair. You either trust me to work in the best interests of D, or you don't. I've been quite open in explaining the reasoning going on. Naming isn't going to add anything.


> I mean the whole idea of client X deciding to ring up Andrei or Walter, NDAs to not disclose their name, and make an executive decision on some language/phobos feature.

Anyone can (and has) sent me emails about D which they wish to be confidential, and I treat them as such, and will continue to do so. People who want to express concerns privately may do so, and those who want to express them publicly can do so (right here) as well.

Please also consider that the proposal for final-by-default comes from Manu, formerly of Remedy Games. Recall that I implemented UDAs ostensibly for Manu & Remedy, but also because I thought it was a great feature for D. But this one I am not so convinced is great for D. The takeaway is I am certainly not doing things just because some client asked for it and to hell with the rest of the community - the evidence contraindicates that.
March 13, 2014
14-Mar-2014 00:00, Andrei Alexandrescu пишет:
> On 3/13/14, 12:49 PM, Dmitry Olshansky wrote:
>> 13-Mar-2014 23:40, Andrei Alexandrescu пишет:
>>> On 3/13/14, 12:38 PM, Dmitry Olshansky wrote:
>>>> Not the same as `final:` inside - the above just means you can't
>>>> inherit
>>>> from A. Funnily enough any new methods in A would still be virtual even
>>>> if nothing can inherit from it!
>>>
>>> Looks like we could improve on this. Is there an enhancement request
>>> available?
>>>
>>
>> None that I know of.
>
> Just played with some code a bit, turns out at least gdc inlines calls
> for final classes appropriately: http://goo.gl/oV8EYu. What would be a
> reliable way to detect that a vtable entry is generated?

Mistake on my part.
This:

final class A {
    int i;
    void f() { ++i; }
    void g() { ++i; }

}
pragma(msg, __traits(isFinalFunction, A.g));
pragma(msg, __traits(isFinalFunction, A.f));

Prints:

true
true

during compilation, which I take as no vtable entries should be generated.

>
>> P.S. I have a strong distaste to the way OOP is currently designed in D
>> anyway. No, I don't propose to change it.
>
> I take it that overridable by default is part of it. What other things
> are not to your liking?

In no particular order.

1. Qualifiers apply to both reference and instance of a class. Recall the ref Object problem and Rebindable!T in Phobos.

(Would be far more fair to simply admit that classes and OOP are about MUTABLE state and close the whole const problem (of instance itself) with them)

2. Related. Apparently OOP was not ready nor prepared to TLS by default scheme. Monitor field per class is an indication of the said fact.

3. Memory management policy coupled with polymorphism. I have plenty of use-cases where providing polymorphic interface is great, but there is no use in GCing these objects. No emplace and dirty work is not a good way out.

4. There is a TypeInfo per class but no type-switch? Just ahwww.

5. Casts look just like plain casts but in fact do dynamic casts. And there is no static one in the sight, nor _documented_ way to do it.
*cast(void**)&object is not nice

6. Related to the 1st one - since class instance and reference are conflated there is no way to do 'composition':
class A{ ... }
class B{
  A a; // this is delegation, a pointer (!)
  void foo(){ a.foo(); .. }
}
Memory layout goes under the bus. There should have been a way to put the contents of class A in the same memory area as B instance.

7. Related to 6. Empty base class optimization, I mean in general using 0 _extra_ bytes per empty class inside of another one.
Mostly can't be done because of :
a) lack of (any form of) multiple inheritance
b) delegation instead of composition, see also 6

8. No this-call function pointers. Delegates are nice but what's the problem with:
class A{ void foo(); }
&A.foo where A is a class to return the equivalent of :
extern(this_call) void foo(A _this);

Having to conjure fake delegates and twiddle with context pointer is both inefficient and silly.

...

~~~ Personal matter of taste ~~~

1. This is not taking the fact that I simply do not see sense in going with anything beyond a fixed-function duo of:

Traits (Extended interfaces, see e.g. Scala) and final/concrete classes.

Any attempts to reuse code otherwise are welcome with plain composition.

2. The root Object in should be an opaque reference. Hashing, toString, opEquals, opCmp belong to standard traits/interfaces.

3. Multiple inheritance with linearizion of inheritance tree.

-- 
Dmitry Olshansky
March 13, 2014
On 3/13/2014 1:09 PM, Andrei Alexandrescu wrote:
> Also let's not forget that a bunch of people will have not had contact with the
> group and will not have read the respective thread. For them -- happy campers
> who get work done in D day in and day out, feeling no speed impact whatsoever
> from a virtual vs. final decision -- we are simply exercising the brunt of a
> deprecation cycle with undeniable costs and questionable (in Walter's and my
> opinion) benefits.

Also,

    class C { final: ... }

achieves final-by-default and it breaks nothing.

March 13, 2014
On 3/13/2014 11:41 AM, Andrei Alexandrescu wrote:
> 2. There's the danger of getting into a design-by-committee rut.

Back in the early days of the C++ Standards committee, I recall some members negotiating in effect "vote for my proposal and I'll vote for yours". I don't see that as a great way to design a language.

Democratic committee processes also involve long, and I mean loooong, timespans for making decisions. Like 13 years from C++98 to C++11.