<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 4 December 2013 12:58, Kapps <span dir="ltr"><<a href="mailto:opantm2+spam@gmail.com" target="_blank">opantm2+spam@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Tuesday, 3 December 2013 at 18:10:43 UTC, Dejan Lekic wrote:<br>
</div><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This is *a radical change*, and instead of "(unknown) people agreed" the community deserves a better explanation why are we switching to final as default storage class...<br>
</blockquote>
<br></div>
Let me state in advance that I believe that in most situations people will leave the default option unless they have reason to (that is, stick with the virtual unless they have reason to mark something final, or stick with final unless they have reason to mark something virtual). For virtual, there is often less reason to realize something should be final as things look like they work until much later. Forgetting to stick a 'final' in front of your function will never give you a compiler error. That being said, some pros / cons of virtual/final by default. Obviously heavily biased.<br>

<br>
1) The most obvious reason is final has better performance. Some effort can be taken to reduce the impact of virtual methods but ultimately there will always be a performance hit. In a large program, this may not be too substantial a hit. I consider this the weakest argument for final-by-default, but others who attempt to deliver as efficient as possible code consider it very important.<br>
</blockquote><div><br></div><div>I think this has a tendency to be underestimated until it is a project requirement. Consider that there may be any number of useful libraries available - many of which didn't explicitly try to deliver the most efficient possible code, by they are still useful libraries nonetheless - but pervasive use of virtual may unintentionally inhibit their usage in performance critical software.</div>
<div><br></div><div>This is not conjecture, I've run in to this professionally on many occasions. And worse than C++, D has 1st class properties, which makes it much more important a consideration than in C++.</div><div>
What I'm proposing is simply that, with this change, it will not be a hidden/unintentional cost, but the placement of the keyword one way or another will result in library authors considering, even for just a moment, the reality of the _choice_ they are making. It can't be default, or the choice will be overlooked and the damage is done, since it can't be revoked.</div>
<div><br></div><div>Library authors are very apprehensive to make breaking changes to their API and go bumping the major version of their software to fix an otherwise trivial performance issue.</div><div><br></div><div><br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
2) A function that is virtual cannot be changed to be final without breaking existing code. If you are writing a library and have a virtual method which you wish to change to final, anyone using that library that overrides your method will have their code break and require substantial design changes if they were relying on simply being able to override your method. If a method was final and is changed to be virtual later on, no code will break unless the developer then decides to change it back to final afterwards.<br>

<br>
3) Related to the above, if a method is not virtual there is nothing you can do about it. A method might be perfectly capable of being virtual without issues, yet if the developer forgot to mark it as 'virtual' you cannot override it even though it may be safe to do so.<br>
</blockquote><div><br></div><div>You can change it easily (open source), or request the change (which usually wouldn't be objected, since it's not a breaking change). And if neither of those are to your taste, you can very easily wrap it as a last resort; in D, 'alias this' makes wrapping things easier than ever. Those aren't options when going the other direction, rather, there is no option... you're simply screwed. And I have been on the receiving end of this on many occasions in C++, and it sucks!</div>
<div>It will be much worse for D, since properties are more pervasive.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
4) If we assume that the statement about people sticking with the default is true (which I strongly believe it is, yet lack actual data for), final by default means more 'virtual' keywords being stuck everywhere. For a language that may already be considered to have too many modifiers to stick in front of your methods, this would add yet another one for many class methods.<br>
</blockquote><div><br></div><div>I have hard experience that shows that even when people know it's a critical performance penalty and a project requirement, they STILL stick with the default, either from habit, or ignorance/inexperience, or they simply forget.</div>
<div><br></div><div>WRT adding additional modifiers, I'd make the argument that looking from the other (current) perspective where virtual is default and you need to explicitly mark functions final everywhere, you will end up with far more 'final' spam than you would with 'virtual' as you suggest.</div>
<div>If that's not the case, then it's likely the truth is that D libraries are over-virtualised, and will suffer performance penalties as a result.<br></div><div><br></div><div>The majority of functions in most OOP classes are properties and trivial accessors which should almost never be virtual. Imagine, making virtual function calls to access trivial properties? They can't be inlined anymore; inlining trivial accessors is one of the most important optimisations for OOP that there is.</div>
<div>If people stick with the default, then D suffers severe performance penalties against C++ and even Java/C#/etc, since nothing can be done to optimise the calls. And like you say, you (and I) agree that most people will stick with the default in most cases unless they have good reason not to (ie, a compile error).</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
5) Marking something virtual is a huge commitment and makes substantial guarantees about implementation details. A simple example is a property. Making a property virtual is a statement that you will never access the field behind the property (assuming there is one), as someone may have overridden the property to use a different backing field or a constant value. This is something that requires actual acknowledgement, yet virtual by default does not require you to think about this as it's automatically virtual. This is actually a mistake I catch myself making not infrequently.<br>
</blockquote><div><br></div><div>Yes, another very important point that I have tried to make many times. I support that it is important to acknowledge this commitment you have made. It can't reasonably be a default commitment, since it has severe performance and maintainability implications.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
A less obvious example is add vs addRange. If you implement a class to extend an existing collection yet add capabilities for storing length by overriding add/remove to increase/decrease length, should you override addRange and add range.length? What if something then overrides addRange for more efficient adding of multiple elements rather than calling add N times, or something that only sometimes calls add depending on the element type or state? These are considerations that require actual thought, and while simply adding a "virtual" keyword to them doesn't mean you thought about the implications, the very action of having to add this keyword makes it a conscious effort and so helps you consider the side-effects of adding it and what it means.<br>
</blockquote><div><br></div><div>+1 hundred :)</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I don't understand how virtual-by-default is even considered for new languages. It provides slight convenience while being error prone. Yet breaking almost every single D program is a huge issue and stability is something that D is desperately trying to achieve. I'd like virtual by default, but it's a hard sell now. I wouldn't mind updating my code for this and I feel it better to do this sort of change now rather than later when more/larger code uses D, but it is still a substantial code break. If it was actually done it would need a transition flag or such to help the process (final by default normally, virtual by default with the transition flag), and likely a virtual keyword implemented well ahead of time so people could start making their changes early and gradually.<br>
</blockquote><div><br></div><div>You mean you'd like virtual-by-default as you say (as is now), or you'd like final-by-default at the cost of the transition?</div><div><br></div><div>There is a proposed transition process across a few releases which should make the transition relatively painless, at least, it wouldn't be error prone, since warnings/deprecation messages would assist the process.</div>
<div>1. 'virtual' keyword is introduced, 'override'-ing unattributed methods is a warning.</div><div>2. it becomes deprecated, but you can still compile with -d.</div><div>3. it becomes an error, but surely you've already taken the opportunity to update your software, right?</div>
</div></div></div>