Nice to @Share?

Fredrik Öhrström fredrik.ohrstrom at oracle.com
Tue Feb 23 07:13:38 PST 2010


I cannot see that "start" is different from any other local variable
that is expected to be mutable when accessed from within a closure. I.e.
the bytecode will use getfield/putfield instead of aload/astore and the
object that it will do getfield/putfield on must potentially be an
environment object separate from the closure object. The initialization
of the field must be a copy from the argument of course.

This BGGA example shows that the environment object that contains start
must exist separately from any closures created using that environment.
(There are simpler situations where the closure object can serve as the
env object.) When v == false, then the env will not be live after gen
has exited. When v == true it will stay alive as long as the closure
stays alive since the closure holds on to it.

public class Test
{
   public static void main(String... args)
   {
      {==>int} f = gen(42);
      System.err.println(""+f.invoke());
      System.err.println(""+f.invoke());
   }

   static volatile boolean v = false;
  
   static {==>int} gen(int start) {
     
      if (v) {
         return {==> start++; start };
      } else {
         start++;
         System.err.println("start="+start);
         return null;
      }
   }
}

When v=true, it prints 43, 44 and when v=false it print 43 and throws NPE.

I am not sure that I really warned about this, my point is that the
environmental object is inevitable because closures == objects and vice
versa. This is not necessarily a bad thing.

//Fredrik

Alex Buckley skrev:
> I think the use of 'start' was rather what Fredrik warned about in 
> http://blogs.oracle.com/ohrstrom/2009/08/using_methodhandles_to_reconci.html
>
> What possible effect can mutating 'start' have?
>
> Alex
>
> David.Moss at ubs.com wrote:
>   
>>> By the way, I am very happy with final (or implicit final).
>>> When I code and find that I need a non-final local variable,
>>> I first try to rewrite the code to avoid to use non-final
>>> before trying to use a mutable object.
>>>       
>> Where des this leave closures?
>>
>> i.e.: what would we need to make the following code do what it is meant to:
>>
>> public class C {
>>     public #int() getSequenceGenerator(int start, int increment) {
>>         return #int() {
>>             int ret = start;
>>             start += increment;
>>             return ret;
>>         };
>>     }
>> }
>>
>>
>> Kind Regards,
>>
>> David.
>>
>> --



More information about the lambda-dev mailing list