Explicit captures in lambda expression
Quân Anh Mai
anhmdq at gmail.com
Tue Jan 7 05:30:41 UTC 2025
Hi,
A feature I missed from C++ is explicit captures in lambda expressions and
from recent events I think that it may be a valuable feature to have in
Java.
JEP-8341785[1] proposes treating loop variables as final inside the loop
body, the main motivation is to allow their usage in lambda expressions
inside the loop body. However, it seems to be withdrawn due to the concern
of making an exception. I believe explicit captures would remove the
condition that the variable being captured needs to be effectively final,
resolving the motivation of JEP-8341785 and many other cases.
JDK-8347047[2] is a bug caused by the implicit capture of the this
reference inside a lambda, which leads to the object never being reclaimed
by the garbage collector, the thing we actually want to capture there is
the result of the method call this.address(). In this case, implicit
captures is very error-prone and it would be better if we can explicitly
declare what we want to capture instead to avoid accidentally capturing
unwanted variables.
As a result, I propose that:
- A lambda expression can optionally have a captures, if that is the case,
all the variables being captured by the lambda expression need to be
declared inside it.
- We can capture an effectively final variable without giving it another
name, but for the others, to avoid confusion, another name for the variable
is needed.
E.g, suppose a, b are effectively final variables and x, y are not:
() -> a; // Allowed, implicit capture of a
[]() -> a; // Disallowed, a is not captured and hence not defined here
[a]() -> a; // Allowed, explicit capture of a
[a, b]() -> a + b; // Allowed, capture 2 variables
() -> x; // Disallowed, cannot implicitly capture non-effectively-final
variable
[x]() -> x; // Disallowed, capture a non-effectively-final without
reassignment
[t = x]() -> x; // Disallowed, x is not defined here
[t = x]() -> t; // Allowed, x is captured and assigned to the variable t
inside the lambda
[t = this.address()]() -> t; // Maybe?
Cheers,
Quan Anh
[1]: https://openjdk.org/jeps/8341785
[2]: https://bugs.openjdk.org/projects/JDK/issues/JDK-8347047
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20250107/d46d339c/attachment.htm>
More information about the amber-dev
mailing list