<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
> the lambda capture rule should be is that the variable can be captured if it is definitely assigned before the lambda, and definitely not assigned after the lambda.</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I'm very confused by what you mean. A lambda can't "unassign" a variable. So I don't see in what cases a variable can be DA before the labmda and definietely unassigned afterwards (ignoring unreachable code in `if(false)` blocks)</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Greetings</div>
<div class="elementToProof" style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Robbe Pincket</div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Van:</b> amber-dev <amber-dev-retn@openjdk.org> namens Attila Kelemen <attila.kelemen85@gmail.com><br>
<b>Verzonden:</b> dinsdag 7 januari 2025 13:31<br>
<b>Aan:</b> Quân Anh Mai <anhmdq@gmail.com><br>
<b>CC:</b> amber-dev@openjdk.org <amber-dev@openjdk.org><br>
<b>Onderwerp:</b> Re: Explicit captures in lambda expression</font>
<div> </div>
</div>
<div>
<div dir="ltr">I like this idea, because I run into bugs of accidentally capturing "this" so many times, and the least of the problems when this causes a crash (like serialization issues), but sometimes it "just" creates a potentially huge unwanted memory retention.
 The workaround of moving the lambda declaration into a separate static method is very-very tedious.
<div><br>
</div>
<div>I do not however care so much about non-final capture (I'm not sure if it should even be allowed). What - in my opinion - the lambda capture rule should be is that the variable can be captured if it is definitely assigned before the lambda, and definitely
 not assigned after the lambda.</div>
<div><br>
</div>
<div>Also, I don't think `[t = x]` is needed, I think that part just complicates the language with very little gain. Just allowing an explicit variable name capture list should be enough.</div>
<div><br>
</div>
<div>Attila</div>
</div>
<br>
<div class="x_gmail_quote x_gmail_quote_container">
<div dir="ltr" class="x_gmail_attr">Quân Anh Mai <<a href="mailto:anhmdq@gmail.com">anhmdq@gmail.com</a>> ezt írta (idõpont: 2025. jan. 7., K, 7:17):<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="ltr">To add more context regarding JDK-8347047, even without the core lib bug, the method is easily misused. The method in consideration looks like this:
<div><br>
</div>
<div>MemorySegment MemorySegment::reinterpret(long size, Consumer<MemorySegment> cleanup)</div>
<div><br>
</div>
<div>`cleanup` is triggered when the returned segment is closed, which for some kind of MemorySegment, is at the time the old MemorySegment instance (this) and the new MemorySegment instance (the returned segment) are garbage-collected. As a result, `cleanup`
 must not reference the old segment instance. It is given a freshly created MemorySegment instance and must use it. However, it is easy to mistakenly use the old instance instead:</div>
<div><br>
</div>
<div>MemorySegment oldMs;</div>
<div>oldMs.reinterpret(size, ms -> free(oldMs));</div>
<div><br>
</div>
<div>While it should be:</div>
<div><br>
</div>
<div>oldMs.reinterpret(size, ms -> free(ms));</div>
<div><br>
</div>
<div>With explicit captures, it is easy to see if oldMs is mistakenly captured as this would not compiled:</div>
<div><br>
</div>
<div>oldMs.reinterpret(size, [](ms) -> free(oldMs));</div>
<div><br>
</div>
<div>Cheers,</div>
<div>Quan Anh</div>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Tue, 7 Jan 2025 at 12:30, Quân Anh Mai <<a href="mailto:anhmdq@gmail.com">anhmdq@gmail.com</a>> wrote:<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="ltr">Hi,
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>As a result, I propose that:</div>
<div><br>
</div>
<div>- 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.</div>
<div>- 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.</div>
<div><br>
</div>
<div>E.g, suppose a, b are effectively final variables and x, y are not:</div>
<div><br>
</div>
<div>() -> a; // Allowed, implicit capture of a</div>
<div>[]() -> a; // Disallowed, a is not captured and hence not defined here</div>
<div>[a]() -> a; // Allowed, explicit capture of a</div>
<div>[a, b]() -> a + b; // Allowed, capture 2 variables</div>
<div>() -> x; // Disallowed, cannot implicitly capture non-effectively-final variable</div>
<div>[x]() -> x; // Disallowed, capture a non-effectively-final without reassignment</div>
<div>[t = x]() -> x; // Disallowed, x is not defined here</div>
<div>[t = x]() -> t; // Allowed, x is captured and assigned to the variable t inside the lambda</div>
<div>[t = this.address()]() -> t; // Maybe?</div>
<div><br>
</div>
<div>Cheers,</div>
<div>Quan Anh</div>
<div><br>
</div>
<div>[1]: <a href="https://openjdk.org/jeps/8341785" data-auth="NotApplicable">https://openjdk.org/jeps/8341785</a></div>
<div>[2]: <a href="https://bugs.openjdk.org/projects/JDK/issues/JDK-8347047" data-auth="NotApplicable">https://bugs.openjdk.org/projects/JDK/issues/JDK-8347047</a></div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</body>
</html>