On Tuesday, 6 January 2015 at 12:07:21 UTC, Joseph Rushton
Wakeling wrote:
If you have final-by-default for classes, and you accidentally
forget to tag a public method as 'virtual', then you can fix
that without breaking any downstream user's code. If by
contrast you have virtual-by-default and you accidentally
forget to tag a public method as 'final', then you can't fix
that without the risk of breaking downstream; _someone_ may
have relied on that function being virtual.
That's a much bigger problem than what you get with inferred
attributes. If you have whole class hierarchy built around a
function which isn't even supposed to be virtual, you'll have a
lot of refactoring to do when it's marked final.
The only way in which downstream code will ever "break" is when
the called function is longer expressed by the interface as
'pure'. Under the new default, this will only happen when the
function *actually stops being pure*. This is good! The only code
which will then break is code which is itself marked 'pure'. The
solution is either to remove 'pure' from the user's function, or
to stop calling the impure function. It's not the end of the
world if a user function stops being pure (@safe, nothrow, etc.).
Since the called function was never marked 'pure', and thus never
guaranteed to be pure to begin with, it was only luck and
convenience which allowed the user to tag his code 'pure' in the
first place. And, as John Colvin just pointed out, with the new
defaults, the user most likely won't even bother to tag his code
'pure', because he knows he will get all the optimization
benefits without the hassle. The only reason to tag 'pure' from
now on will be to *guarantee* it. At that point, you *want* your
code to break, but only when your function actually stops being
pure.
With D's existing default (and with code marked with the
suggested new attribute 'extern(noinfer)'), you have another
reason why your 'pure' function won't compile. Indeed, it's
already broken. I ask you, why should a user have to wait until
someone marks a function 'pure' to get the advantages of its
purity, when the compiler already has everything it needs in
order to grant those advantages? In the rare case where you
actually want to revert to the way D is now, then you simply have
to pay the price, which is the *same* price that everyone is
already paying now.