Thursday, December 27, 2012

My Final Word (Almost)

In "Final Parameters and Local Variables", Dr. Heinz M. Kabutz rants against the generalized used of the final keyword in Java code. For him, this is a "trend' and an "idiotic coding standard".

I'm a firm believer of the complete opposite.

As a software developer, I spend most of my time reasoning about code. Anything that can make this reasoning easier is welcome. Good practices like short methods and descriptive names fall in this category. I believe immutable variables do too.

Immutable variables simplify reasoning because they ensure a stable state within a scope, whether it's a whole class or a single method. Having established invariants is a tremendous help in understanding code.

Whether it is with my own code or not, I've experienced time and again that my mental load was way lower with immutable variables than mutable ones. Maybe it's just a limitation of my own brain power, but, to me, less mental load translates in deeper understanding. And to the contrary, finding out amid-function that one of its argument has been reassigned creates an intense sense of confusion, prompting to re-read the method again. And again.

Of course, this isn't 100% true in Java, mainly because its default data structures are unfortunately mutable. But still, the comfort gained by using the final keyword everywhere, and actually letting your favourite IDE do it for you, far outweighs the small visual clutter it creates.
Unsurprisingly, I'm of the same opinion about early returns and loop breaks, but this is for another debate...

Dr. Kabutz will certainly argue that this is a matter of personal discipline or talent to ensure that one doesn't mess with invariants, because he doesn't "need the compiler to tell [him] this". Again I disagree. I don't trust myself to be on top of things at all time so I want the compiler to tell me everything... and more. I want Findbugs to scrutinize everything I write and break the build if I've been sloppy. I want Checkstyle to reject my code if it isn't compliant to whatever standard is enforced on the project I'm working on.

I do agree on one thing that Dr. Kabutz said though, which is that using the final keyword everywhere in printed books' code snippets is an annoyance. Indeed, books formatting rules constraints on code samples are so stringent (think 71 columns) that the rules of readability are tipped towards "less code as possible".

What is your experience with final variables everywhere? Love, hate or ...

5 comments:

RR said...

+1, found myself using final more often these days, and agree with your reasoning. Possibly because I've been using Scala for a couple of years now.

Peter Kofler said...

If we would all have the same opinion, it would not be a good discussion, would it? ;-) I see both your and Heinz' points. I used to make everything final as possible for many years, but some time ago I started favouring the shorter signatures and stopped using final parameters. In fact, if you keep your methods as small as proposed by Uncle Bob's Clean Code, it does not matter if you make them final or not because methods are super small. On the other hand, then, if methods have only one or two parameters, making them final also does not impair readability. But for your typical legacy crap, 20 arguments and more, making them final might double the length of the signature. The method is too large, has too many arguments, etc. So maybe this is the wrong discussion at all.

Same is true for local variables, which I still make final if possible. If you have small methods, there is max. one or two local variables, so final or not, no readability problem and also no need to be save.

Gabriel Kastenbaum said...

+1
"final" saved my day so many times.
I like that the compiler tells me if I don't use the variable. And I love that he temms me if me "params" variable is used twice for different purpose.

yfyf said...

I know I will sound like a troll, but do you really still believe that things like:

"public static final int"

helps you reason about code? To me, it's all just noise which distracts me from the essence of what's happening without providing any substantial benefit.

David Dossot said...

Thanks all for your comments.

To me there are two distinct problems: the what and the how.

There is no doubt that the how is ugly in Java. "public static final int" is verbose, but that is the Java way. If one has the possibility, it would be better to use a terser JVM language, one that has better support for immutability like Scala or even better Clojure.

But if you're stuck in Java, then the how is what it is and what really matters is the what. The what is immutability above all and the numerous benefits it brings when it comes to reasoning about a program's state.