Effectively final

Steven Simpson ss at comp.lancs.ac.uk
Tue Aug 16 02:56:39 PDT 2011


On 16/08/11 01:51, Stephen Colebourne wrote:

[snip: lots of syntax options for permitting mutable locals]
> int #total = 0;
> list.apply(#{item ->  total += item});
>
> ie. a way to introduce a local variable that can be managed safely.

For the simple example given, you could translate 'total' into an 
AtomicInteger, but if there are other variables to be accessed, you'd 
have to box them together, and make the whole lambda synchronize on it, 
or at least from the first use of the box to the last.  Trying to patch 
the call site like this doesn't seem to be particularly promising.  The 
alternative is to require List.apply to make additional guarantees about 
how it executes the lambda.

Would it not be better to let List.apply get on with its potential 
parallelism, and define other methods that do make extra guarantees, 
e.g. that the lambda will be executed serially, or even on the caller's 
thread?

Tim's cases include, for example, setTimeout(int, Runnable), which must 
make such a guarantee, if only informally in its documentation.  To be 
more formal:

    * Declare setTimeout(int, @Callback Runnable).
    * When a lambda is assigned to a @Callback Runnable, allow the
      lambda body to mutate locals (without error or warning).
    * Don't permit a @Callback Runnable (which is tainted) to be
      assigned to a plain Runnable (without error or warning).

This way, the likes of List.apply don't have to make any guarantees, 
requiring the caller to make corresponding ones (automatically achieved 
by not being generally allowed to mutate locals).  Meanwhile, setTimout 
makes additional guarantees, to the convenience of the caller, who is 
specially permitted to mutate locals.

Cheers,

Steven


More information about the lambda-dev mailing list