If you had money to place for a bounty, what would you choose?

Kapps opantm2+spam at gmail.com
Tue Dec 3 18:58:53 PST 2013


On Tuesday, 3 December 2013 at 18:10:43 UTC, Dejan Lekic wrote:
> 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...

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.

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.

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.

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.

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.

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.

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.


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.


More information about the Digitalmars-d mailing list