Effectively final

Tim Fox timvolpe at gmail.com
Tue Aug 16 08:45:26 PDT 2011

The point I was making was in response to your assertion that inherently 
serial code will become less common as time goes on. Actors frameworks 
(and other hybrid frameworks like node.x) are all based around 
inherently serial code, and I don't see them dying out yet.

Quite the opposite, I see them getting more popular :)

On 16/08/11 16:25, Howard Lovatt wrote:
> I don't see that the actor or FJ type frameworks are effected much, 
> because the messages are immutable, e.g. a standard actor example:
> http://java.dzone.com/articles/scala-threadless-concurrent
> Recoded in Java would be something like this:
> public class Actor extends FJTask {
>   private Queue messages ...
>   public void accept( final Object message ) ...
>   public Object acceptAndReply( final Object message ) ...
>   public Future<Object> acceptAndReplyLater( final Object message ) ...
>   protected void reply( final Object response ) ...
> protected Object getMessage() ...
> }
> |10.||public class Accumulator ||extends| |Actor {|
> |11.||public void run() {|
> |12.||int sum = ||0;|
> |13.||for(;;) {|
> |14.|final Object message = getMessage();
> |15.|if ( message instanceof |Accumulate ) { ||  sum += 
> ((Accumulate)message).n; ||}|
> |16.|else if ( message instanceof |Reset ) { sum = ||0; }|
> |17.|else if ( message instanceof Total ) {  reply(sum);  break;
> |18.||}|
> |19.||}|
> |20.||}|
> |21.||}|
> The lambdas might prove useful for the messages, that are immutable 
> anyway, but the actors themselves would always be instances of a class 
> because you need to be able to create more actors as the program runs 
> and you can't do this with a lambda (or a closure many other 
> language). As I said at the beginning I don't see that an Actor 
> framework would change much one way or the other if Lambdas could 
> mutate a variable or not.
> Cheers,
>  -- Howard.
> Sent from my iPad
> On 16/08/2011, at 6:57 PM, Tim Fox <timvolpe at gmail.com 
> <mailto:timvolpe at gmail.com>> wrote:
>> On 16/08/11 12:36, Howard Lovatt wrote:
>>> I think the correct decision has been made, inherently serial code 
>>> will become less common as time goes on.
>> The growing popularity of actor model implementations (actors of course
>> only allow serial execution of code in the actor), e.g. Erlang and Akka,
>> and the growing popularity of languages which are inherently serial
>> (e.g. JavaScript) are a clear counterpoint to your argument. Also look
>> at webworkers, node.js. I could go on.
>> I'd argue the current trend is quite opposite to what you see. Non
>> serial code will become unusual (because concurrency is hard), and
>> serial code will become the norm (because it's easier to code,
>> especially for the web developer masses). Systems will scale by having
>> multiple "islands" of serial code (e.g. multiple actors in the actor 
>> model).
>> Please note that just because all code is executed serially does not
>> mean you can't exploit parallelism. You can do fork/join type stuff by
>> sending messages to other "islands" and reassembling the results as they
>> come back.
>>>  Therefore optimizing new features for parallel execution is the 
>>> correct path to take and also constant with Java's past of taking 
>>> existing concepts into the mainstream. When Java was introduced the 
>>> concentration on objects and garbage collection was not mainstream 
>>> and was opposed by many. I think the same will happen with mutable 
>>> data and serial execution and it is nice that Java is once again 
>>> daring to be different and adhering to the mantra that less is more.
>>> Cheers,
>>>  -- Howard.
>>> Sent from my iPad
>>> On 16/08/2011, at 4:56 PM, Steven Simpson<ss at comp.lancs.ac.uk 
>>> <mailto:ss at comp.lancs.ac.uk>>  wrote:
>>>> 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