Terminology
Alex Blewitt
alex.blewitt at gmail.com
Thu Dec 17 04:24:20 PST 2009
We've been debating various levels of lambdas, and using modifiers like
'static' and 'instance' without necessarily agreeing on what we are implying
by those terms. In addition, the definition of the location (whether it is
inside or outside a method, or even whether it is inside or outside another
lambda) is lacking clear terminology.
So, here are some cases:
Location A.
public class A {
private ... a = #() {...};
}
Location B.
public class B {
public void b() {
... a = #() {...};
}
}
Location C.
public class C {
public void c() {
... = #() {... c = #() {...} };
}
}
Capturing:
Capture D.
... d = #int() { 42 }; // Captures nothing i.e. a 'pure' lambda, not a
closure
Capture E.
public class Ea {
public void eb() {
int x = 42;
... e = #int() { x *2 }; // captures local variable in stack scope
}
}
Capture F.
public class Fa {
private int x = 42;
public void fb() {
... f = #int() { x*2 }; // captures implicit 'this.x' reference
}
}
Capture G.
public class Ga {
private static int x = 42;
public void gb() {
... g = #int() { x*2 }; // captures implicit 'class.x' static reference
}
}
Capture H.
public class Ha {
public void hb() {
... = #int() { int x = 42; ... g = #int() { x*2} }; // capturing stack
scope from within another lambda
}
}
It would be good if we had some kind of wiki to record these, and/or make
them publicly available, and determine what we're going to call each one.
Furthermore, we've been using terms like 'static' - the strawman
distinguishes between accessing static members and non-static members
(determined by whether the fields are visible or not). Whilst I think it
useful to be able to declaratively restrict the scope of certain lambdas,
the compiler should be able to promote lambdas to restricted or static scope
automatically based on whether or not any fields are accessed or not.
For example, Capture F above accesses an instance field of the current
class. However, consider:
public class F2 {
public void f2a() {
... f2 = #int() { 42 };
}
}
in this case, the method (f2a) is still an instance method, but the lambda
f2 does not capture any instance-specific scope. So it could be promoted to
be a constant or shared lambda; in fact, one could argue that the
instantiation of that lambda (assuming it's translated to an inner class,
then, it would be a static inner class) would be a static final. So it might
transform to:
public class F2 {
private /* ACC_SYNTH etc */ static class f2 {
protected int f2() { return 42 };
}
private static final f2 = new f2();
public void f2a() {
... f2.f2()
}
}
The point of observing this optimisation is to be able to define what
conditions this might hold, rather than purely the call-site. Clearly a
lambda defined in a static method should only be able to see static fields;
however, a lambda defined in an instance method doesn't have to see instance
fields of the enclosing class. We might have keywords to provide enforced
stricter visibility, but the compiler should be intelligent enough to
auto-demote where necessary.
Alex
More information about the lambda-dev
mailing list