Effectively final effective?
Reinier Zwitserloot
reinier at zwitserloot.com
Sat Feb 27 14:25:49 PST 2010
John, you're making the argument that something is so natural it doesn't
need explaining.... by explaining it.
As long as you need to explain it, it's obviously not the "non-surprising,
obvious" behaviour you think it is.
--Reinier Zwitserloot
On Fri, Feb 26, 2010 at 9:32 PM, John Nilsson <john at milsson.nu> wrote:
> On Fri, Feb 26, 2010 at 2:09 PM, Reinier Zwitserloot <
> reinier at zwitserloot.com> wrote:
>
>> 3. Variables accessed in closures will be silently copied, with the copy
>> inside the closure being final, but the variable outside of it being
>> mutable
>> (but, as the closure gets a copy, any mutations don't show up in the
>> closure). I've filed this away as crackpot, where it'll hopefully remain,
>> as
>> this is going to be very surprising to a lot of programmers and the only
>> way
>> this surprise is going to become obvious is after many hours spent
>> debugging.
>>
>
> So before this is filed away, let me try again and explain why this is not
> surprising and in fact the obvious behaviour.
>
> The variable from the outside scope is "captured" at the time then the
> lambda is created. In the same manner as any variable is carried into
> another scope there and then.
>
> int a = 1;
> int b = 0;
> {
> b = a;
> }
> a = 2;
> //At this point b is expected to be 1, the value of a inside the block. It
> is not expected that b has somehow been equated with the a variable just
> because there is an equal sign implying that relation.
>
> In the same manner you expect
> for(Integer i : asList(1,2,3))
> aList.add(i);
> to produce a list containing 1,2,3 and not a list containing 3 (the last
> value of i)
>
> So there is already a precedent for a semantic of capturing a value, not a
> variable.
>
>
> Now in ordinary blocks we are free to mutate variables from the outside
> scope inside the inner scope. However as these blocks are exectued in the
> same order as they are declared this is not a problem. With lambdas and
> inner classes the definition is decoupled from the execution, which means
> that the outer scope might not even exist at the time of execution. In
> previous versions of Java this was solved only allowing final variables
> inside inner classes. As they can't be mutated in either scope there is no
> mutation order to care about.
>
> So by continuing this line of reasoning, we simply continue to view them as
> immutable inside the inner class/lambda but relax the requirement that they
> are mutable in the defining scope. Thinking that it is the value that is
> captured, not the variable.
>
> BR,
> John
>
More information about the lambda-dev
mailing list