capturing (or not) mutable local variables

Reinier Zwitserloot reinier at zwitserloot.com
Sat Nov 27 08:44:24 PST 2010


That sounds a bit defeatist!

Just because a sizable chunk of programmers casually write code that
includes an active bug or is extremely fragile doesn't mean we should just
throw in the towel.

Work should perhaps be done on the warning / error messages. For example,
include a URL to a page that serves as a tutorial for the more complex java
rules, such as why you can't assign a List<Integer> to a List<Number>. But,
that's not a job for lambda-dev, and doesn't have to be done right now. The
exact wording of error messages aren't part of the java spec, fortunately.

I think PHP shows what happens when one always takes the most direct
pragmatic solution to any problem. I assume I don't have to elaborate much
on why PHP indicates this is not a particularly wise move.

There's also a decent chance someone with absolutely no understanding as to
why mutables in (non-thread-local) closures are a bad idea will nevertheless
be coached into doing the right thing. The error message will doubtlessly
reference the notion that _final_ locals _can_ be accessed in the closure.
Making a copy final is a lot simpler than the array/AtomicX workaround, and
so happens to be the superior solution too.

A second benefit is that, while the one that wrote the code may well be
clueless about what multicore implies, someone else reviewing this code will
have an easier time identifying what's going on. This is quite java-esque -
a field ref can't possibly invoke code. A local variable can't possibly be
involved in a race condition. It's the basis upon which more complex
reasoning can be performed. An 1-size array/AtomicX is an easily visible red
flag.

At some point I'd like to see a still visible but less convoluted way of
doing this, for example by adding a keyword that can be applied to a local,
but there's no particular need to do this for the first release of closures
in java. An advantage of doing it later is that there will be far more
experience to base further language changes on.

 --Reinier Zwitserloot



On Sat, Nov 27, 2010 at 12:54 PM, Stephen Colebourne
<scolebourne at joda.org>wrote:

> On 26 November 2010 17:13, Mark Mahieu <markmahieu at gmail.com> wrote:
> > On 26 Nov 2010, at 10:58, Doug Lea wrote:
> >> The workarounds like using 1-slot arrays add a level of
> >> indirection to subvert the shallow-only provision.
> >> Which seems tolerable.
> >
> > It's tolerable if the workaround is employed with a good understanding of
> its limitations, but it has become a common approach to simple
> inconveniences with final variables used in relatively innocuous contexts.
>  My fear is that it's a workaround which will find itself used in far less
> tolerant situations through the simple virtues of being well known and long
> established.
>
> Agreed. And there is a connection to generics wildcards too. In both
> cases, restrictions were/are added to the language for good reasons -
> to keep the language safe. (For generics I'm thinking of casting a
> List<Integer> to a List<Number>, and many other cases as in the huge
> FAQ). What happens is:
> - the developer tries to perform the "bad" thing
> - the compiler stops them
> - the developer curses the compiler
> - the developer finds the quickest hack
> In my experience, most don't worry about WHY the thing was "bad" they
> just learn the hacks (and aren't worried if the hack is safe). For
> generics, that might be using a raw type. For no access to mutable
> variables, its the length one array.
>
> While I can entirely see why the mutable variable restriction is
> desirable from a correctness POV, I'm far from convinced that it is
> beneficial from a practical POV, and may actually be harmful (because
> only a fraction of developers understand the restriction). As such,
> allowing mutable access may well be better overall. Although, some
> kind of middle ground like Doug suggests would be good.
>
> (Note that it could be argued based on the above, that mutable access
> via arrays should be blocked to force an object based workaround like
> AtomicRefs)
>
> Stephen
>
>


More information about the lambda-dev mailing list