capturing (or not) mutable local variables

Llewellyn Falco isidore at setgame.com
Tue Nov 23 17:13:58 PST 2010


proposal for local variable capture:

There are many cases in which local variables are useful in the scope of
lambdas, but the basically break down into 2 cases

1: need to read a local variable
2: need to change a local variable

The purpose of the this proposal is to suggest a way that is but clear and
easy to write, but also follows "the pit of success"; namely, the code does
not act in a Surprising manner to the average, uninformed developer.

Let's look at the first case: read a local variable.

// create filters for the numbers 1 - 10
for(int i = 0; i < 10; i++)
{
  filter(#{f ->  f == i});
}

Of course this doesn't work in many languages, and won't compile in java.

The work around is of course to
// create filters for the numbers 1 - 10
for(int i = 0; i < 10; i++)
{
  final int i2 = i;
  filter(#{f ->  f == i2});
}

I would like to suggest that java lambda's do this. Namely, if a local
variable is *only read* create a second reference to the local variable, and
transparently use it instead.

Doing this would create the "pit of success" that main other languages have
missed. Namely, the code would do as expected, even to the uninformed java
programmer.


The second case is  where you need to track some common variable.

int i = 0;
createUniqueIds(#{i++});

Here, it's important to be able to have access to i otherwise it would
conflict.
this also will not compile in java.

the workaround of course is
int i = 0;
final int[] i2 = {i};
createUniqueIds(#{i2[0]++});


This of course becomes an issue inside of a loop
int j = 0;
for(int i = 0; i < 10; i++)
{
  createUniqueIds(#{ j++});
}
does this create 10 different j's. NO, again the "pit of success" would
imply no duplicate Id's across all 10 calls to createUniqueIds

so the result should be
int j = 0;
final int j2[] = {j};
for(int i = 0; i < 10; i++)
{
  createUniqueIds(#{ j2[0]++});
}

So I am suggesting that the way local variables are handled differs based on
whether or not the use of the variable is Read only access or Write access.

To be clear, assume the following
int j = 0;
for(int i = i; i < 10; i++)
{
  createUniqueIds(#{ j+= i});
}

would pre-compile to

int j = 0;
final int j2[] = {j};
for(int i = i; i < 10; i++)
{
 final int i2 = i;
  createUniqueIds(#{ j2[0]+= i2});
}


I believe handling these 2 cases separately would be the least surprising to
everyone, avoid many common mistakes made in other languages, and yet keep
the syntax clean and simple. Achieving the "pit of success"

If there is a situation I haven't thought of, that would create a puzzling
pit of failure, please let me know (I'm not sure I've gotten everything...)



Thanks,

Llewellyn Falco
http://bit.ly/lambdas


More information about the lambda-dev mailing list