Effectively final effective?

John Nilsson john at milsson.nu
Sat Feb 27 15:36:35 PST 2010


Am I correct in interpreting the 4 sentiments listed below like so:

Given this code

List<()->int> funs = new ArrayList<>();
for(int i = 0; i < 3; i++)
  funs.add(()->i)
for(()->i f : funs)
  System.out.print(f.());

The following is the result

1. Prints: 333
2. Compiler error at i++ (mutating a final variable)
3. Prints: 123
4. Compiler error at ()->i (trying to access a non-final var)

BR,
John

On Fri, Feb 26, 2010 at 2:09 PM, Reinier Zwitserloot <
reinier at zwitserloot.com> wrote:

> There are so many different sentiments floating around that its hard to
> tell
> the forest from the trees, but as far as I understand it, these are the
> three sentiments I've heard:
>
>  1. Variables accessed in closures should be silently moved into the heap.
> I
> haven't yet heard anything from this camp about what to do with "volatile",
> which would be a useful construct to them have on such local variables.
> This
> is somewhat tricky when the closure is run in another thread.
>
>  2. Variables accessed in closures will be made implicitly final. Any
> attempt to mutate them, either in the closure or outside of it, generates a
> compiler error. This camp is furthermore split into two: One camp wants a
> keyword of some sort to get #1 behaviour (so, _explicit_ movement to the
> heap), the other says that AtomicReference, AtomicInteger, and friends are
> good enough.
>
>  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.
>
>  4. As with anonymous inner classes, variables cannot be accessed at all
> inside closures unless they are marked explicitly final.
>
>
> I'd say that with no distinction between safe and unsafe closures, Only
> option #2 (either variant), with option #4 as a very distant second, is
> sensible, and with safe/unsafe closures, Option #1 for unsafe closures, and
> either #2 or #4 for safe closures, seems reasonable. Exactly how to proceed
> is no clear to me, as this discussion seems to be heading into a painting
> the bike shed direction.
>
>
> NB: Jesse, regardless of the pros and cons of making a backwards
> incompatible java 2.0 release, Java 7 most assuredly is not going to be
> such
> a release, so whatever ideas you come up with, if they aren't backwards
> compatible, the only way its going to happen is for closures to not make it
> into Java7, and for Java8 to be a Java 2.0 release, which even then is very
> very unlikely. Mark Reinhold explicitly mentioned during Devoxx that he
> considers any attempt to make Java 2.0 to be rife with second version
> syndrome.
>
>
> > On Thursday, February 25, 2010, Paulo Levi <i30817 at gmail.com> wrote:
> > > Final should have been the default, non null should have been in the
> > > language (and default), constructors should have not been allowed to
> call
> > > protected methods, closures should have come on day one, reification
> > should
> > > have been included in generics, i miss map and reduce on arrays &
> lists,
> > i
> > > like list generators and RIIA and would love it in java.
> > >
> > > The discussion is if it is worthwhile to allow final by default for
> > captured
> > > variables in lambdas considering that
> > > a) anonymous classes have the opposite behavior, so things get slightly
> > > inconsistent.
> > > b) it is safer for threaded use.
> > >
> > >
> >
> >
>
>


More information about the lambda-dev mailing list