crazy idea: weaken the effectively final restriction
Attila Szegedi
szegedia at gmail.com
Wed Oct 6 19:45:32 UTC 2021
My personal code style is so far on the other end of this spectrum that I wouldn’t ever want this feature. I notoriously single-assign all my local variables to the point of spelling out “final var” just to make sure the compiler catches me if I deviate from it. Very rarely I’ll settle for reassignment (mostly in a loop that accumulates a value. I could do away with most of those too if I could tell the Java compiler to transform tail recursive methods into loops.) Ultimately, I’d never reassign a method parameter. Yes, I declare those as “final” too; my Java code is full of “final” keywords but what can I do when immutability ain’t the default…
I’m not trying to look down from a high horse and champion this as the ultimate style everyone should adopt, but it works for me. Gives me a peace of mind when my variables don’t vary much. It sure is easier for me to read and reason about my code when I revisit it after some time if I don’t have to worry about a variable changing further down the method once I understood the first and only expression that computes its value.
Attila.
> On 2021. Oct 6., at 19:56, John Rose <john.r.rose at oracle.com> wrote:
>
> On Oct 5, 2021, at 2:55 PM, mark.yagnatinsky at barclays.com<mailto:mark.yagnatinsky at barclays.com> wrote:
>
> Runnable f(String s) {
> s = normalize(s);
> return () -> println(s); // no can do: s is not effectively final
> }
>
> However, this seems a bit silly because although s is not final throughout the entire method, it's final where it actually matters.
>
> As the experts have said, it is by design that the
> finality can be applied to the declaration *regardless
> of use*. This yields a language that is easier to
> reason about. (Yes, we did spend a lot of complexity
> budget elsewhere on lambdas as poly expressions,
> which nobody understands. To excuse that, that
> bit of magic happens during overload resolution,
> which nobody understood anyway.)
>
> Namely, it is final from the point of capture to the end of the method, and that's the only condition we need to avoid those annoying questions.
>
> I have wanted this feature from time to time, but
> here’s another indication that it won’t pull its
> weight (of complexity): You can easily, even
> automatically (with IDE help) work around the
> limitation, simply by rebinding the variable
> you intend to capture. That’s the cost of
> using the simpler (more reusable) semantics
> of effectively final variables: Sometimes
> you need a second binding if the system
> cannot read your mind about how you
> are using the first binding.
>
> Runnable f(String s) {
> s = normalize(s);
> var s1 = s;
> return () -> println(s1); // fixed it for you!
> }
>
> Something’s gotta give: Either more mind-reading
> rules for bindings, or more bindings. This is arguably
> the more Java-like approach.
>
> Note also that the worst kind of mind-reading can
> happen when a maintainer reads your code. In that
> case, the maintainer will surely prefer the more
> transparent (though ceremonious) formulation
> with s1.
>
> Full disclosure: As a coder I grumble every time
> I have to write an “s1”. But as a reader of code I
> don’t mind them so much.
>
> HTH
>
>
More information about the jdk-dev
mailing list