capturing (or not) mutable local variables

Vincent Sevel vincent at sevel.eu
Mon Nov 22 15:36:40 PST 2010


Hi Brian,

> Safety mechanisms do not need to be perfect to be useful.  Your arguments seem to center around "I can climb the fence, so there's no point in having it."  This argument is, to be blunt, silly.  The design principles of the Java language stress safety, even if there are cases where such safety guards can be "casted away" by a sufficiently motivated user.

here were the main ideas: the final requirement on variables
 - protects only a very limited number of use cases
 - gives a false sense of protection for all the other use cases that
do require protection
 - is useless and counterproductive in a large number of legitimate
use cases, where ugly workarounds have to be used (eg: the final array
wrapper)
additionally: the real issue
 - is not with the variable being final or not,
 - but with the closure not respecting the api contract in terms of
multithreaded safety

With all the messages going back and forth, it strikes me how much
energy is put in defending the final variable, compared to the forest
of all the other use cases, such as:

final List square = new ArrayList();
list.forEach(#{ e -> square.add(e*e); });

How is that really different from your simple broken example? Why
would we be ok with that one, but not with yours? Should not we be all
equally screaming 'please do not make this non thread safe closure
passable to this multithreaded method'?.

> People will do this, they will do this without thinking, and their code will be broken. It is very hard, even for experts, to get this right.

You realize, of course, that this exact sentence applies to the example above.

>> public void forEach(@Multithreaded Foreachable block) {...}
> We explored these issues in the JSR-166 expert group several years ago.  The basic problem is that we don't have a way of reliably expressing "reference to thread-safe object" in the type system (either statically or dynamically), so these things revert to being documentation rather than type assertions.

It is documentation that tools (like compilers) can take advantage of,
so it is already much better than javadoc, and still way better than
naming convention.

>> for that matter, you should probably name your loop method forEachMT.
> Under consideration.  Though my intuition is that (a) such a convention will be hard to stick to and (b) in five years it will probably look silly.

There are predecessors: SwingUtilities.invokeLater/invokeAndWait. Does
it look silly? May be, but at least, while missing a mean to express
thread specific constraints on a contract, we can recognize that it
has some greater visibility than if it was hiding in the javadoc,


I see the final requirement on variables as bureaucracy: adds little
value, and mostly gets in the way of code agility. It is just a lost
opportunity, but java developers have come to cope with it. However, I
have battled enough with the double-checked locking anti-pattern, and
unproperly synchronized code to know that whenever you provide an API
that does something with threading, it needs to come with a red flag.
Fix that, and you will realize that the mutable variable is not that
of a problem.

But may be a reality check might be helpful: send me the forEach
documentation and signature, and I will ask the 25 developers in my
company to tell me what is the outcome of the square example.

Thanks for listening. Cheers,
Vincent


More information about the lambda-dev mailing list