Options for accessing local variables
Stephen Colebourne
scolebourne at joda.org
Sat Mar 20 05:05:53 PDT 2010
This is a list of possible different ways to link local variables to
lambdas. (I spoke to Alex at QCon London about the list).
In each case, an example is given, but the syntax isn't that important
- its the semantics we are picking. (I've used annotations instead of
keywords as it gets the point across more easily:
1) Full access to local variables by reference:
int total = 0;
Utils.each(list, #(String str) { total += str.length() });
// total is sum of string lengths if each() is not threaded
2) Access to local variables if they are marked by a key word or annotation:
@Shared int total = 0;
Utils.each(list, #(String str) { total += str.length() });
3) No access to local variables
(example not possible in style it is written - use an AIC?)
4) Only final local variables can be accessed (as with AIC)
final int[] total = new int[1];
Utils.each(list, #(String str) { total[0] += str.length() });
5) Local variables are accessible but copied on construction:
int total = 0;
Utils.each(list, #(String str) { total += str.length() });
// total still zero here - need different approach for the example
6) Import local variables by reference:
int total = 0;
Utils.each(list, #(String str : @Share total) { total += str.length() });
6a) non-imported local variables cannot be seen
6a) non-imported local variables are copied on construction as per #5
7) Import local variables by copy on construction:
int total = 0;
Utils.each(list, #(String str : @Copy total) { total += str.length() });
// total still zero here - need different approach for the example
7a) non-imported local variables cannot be seen
7a) non-imported local variables are accessed by reference as per #1
8) Mark the lambda as local, allowing full access to local variables:
int total = 0;
Utils.each(list, @AccessLocal #(String str) { total += str.length() });
8a) if annotation not present local variables cannot be seen
8a) if annotation not present local variables are copied on
construction as per #5
9) Mark the lambda as multi-thread, copying locals on construction:
int total = 0;
Utils.each(list, @CopyLocals #(String str) { total += str.length() });
9a) if annotation not present local variables cannot be seen
9a) if annotation not present local variables are accessed by
reference as per #1
10) Mark the destination method as local with keyword or annotation:
int total = 0;
Utils.each(list, #(String str) { total += str.length() });
method declared as:
public <T> void each(Collection<T> coll, @Local Block1Arg<T> block)
which accesses locals by reference.
11) Mark the destination method as multi-thread with keyword or annotation:
int total = 0;
Utils.each(list, #(String str) { total += str.length() });
// total still zero here - need different approach for the example
(not a closure)
method declared as:
public <T> void each(Collection<T> coll, @MultiThread Block1Arg<T> block)
which accesses locals by copy on construction.
NOTE: with #8 and #9, you can't tell from the call-site which type it is.
I'm sure that there are other possibilities. And I've not directly
addressed the question of "this" (which can be inferred to some degree
by picking one of the choices above).
I'd also note that "copying on construction" might be a simple copy of
the reference, or a full clone.
So, in summary - variables can be accessed by reference, or copied on
construction. They can be annotated in a variety of different ways to
provide choice or to restrict between these two basic choices.
Hope this helps someone. I'm offlist for about 3 weeks now.
Stephen
More information about the lambda-dev
mailing list