<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font face="monospace" size="4">As usual, everybody's right :)<br>
<br>
I think Ron has captured the stewardship argument about how we
would like users to view the language: that the two sorts of
loops, assuming each are "well behaved", should be
interchangeable, refactorable to each other, etc, and that the
differences in scoping should be an "implementation detail." <br>
<br>
And Maurizio is correct that people have formed their own mental
models about how both kinds of loops work, and for some, changing
them will be "fixing a bug", and for others, it will be taking
something straightforward (x++ in the loop header is straight
mutation, nothing to see here) and distorting it. <br>
<br>
Given that we have the language we have, what to do here is mostly
based on a cost-benefit analysis where both the costs and benefits
are subjective. And, I think it's kind of close; I think there's
a simple thing we could do here that would be a net improvement,
but we could also justify (as we did in 8) doing nothing special
here. <br>
<br>
Honestly, I think both kinds of loops are weak; the "legacy C"
loops suffer mightily from having copied too literally (and yet
poorly) from C, with the result being that they are both too
general for the average case and too weak for the general case.
The foreach loops suffers from the (explicit) desire to capture
the 90/10 point. The result being that they both have irritating
sharp edges that make you want to refactor from one to the other,
and sometimes back. Which makes gratuitous asymmetries in how
they interact with other features (scoping and capture) even more
irritating, because one forced refactoring will then force another
refactoring. <br>
</font><br>
<br>
<div class="moz-cite-prefix">On 10/23/2024 9:52 AM, Maurizio
Cimadamore wrote:<br>
</div>
<blockquote type="cite" cite="mid:ea265b3a-67a0-4a9f-b74c-db7092b0d30b@oracle.com">
<p><br>
</p>
<div class="moz-cite-prefix">On 23/10/2024 13:00, Ron Pressler
wrote:<br>
</div>
<blockquote type="cite" cite="mid:DA336424-4BFB-404F-9AAC-A006FED78A80@oracle.com">
<pre>That x really means something subtly different in the foreach loop and
the classic loop is more of an implementation detail. I don’t know the
history of that choice, and it did predate lambda, but if it was made to
allow a final index to be captured in an index class, then
capturability is the motivation for that detail.</pre>
</blockquote>
<p>I don't disagree that is a matter of perspective (I called it
subjective). As I stated:</p>
<p> </p>
<blockquote type="cite">How you "fix" this largely depends on (a)
how you find this asymmetry annoying (which likely depends on
exposure - and different code bases might have different levels
of that) and (b) how much your developer intuition is trained to
view the loop induction variable as a single mutable *variable*,
or a series of *values* where each value is derived from the
former in a controlled fashion. I don't have a strong (enough)
opinion on either :-)</blockquote>
<p>IMHO both (a) and (b) are subjective calls. I feel that some
developers will stand by the asymmetry because for-each is
special, and doesn't use mutation (no need to do `i++`) so _of
course_ you get a "fresh" `i` on a for-each iteration (but not
in an imperative for loop). This is further reinforced by the
fact that you can add `final` on for-each variables, but not in
the imperative loop induction variables.<br>
</p>
<p>Other developers will find this distinction annoying, because
in a well-behaved counted loop, the mutation of the induction
variable is so controlled that it can largely be ignored (and be
treated as an impl detail).</p>
<p>I think both views have their own merits<br>
</p>
<p>Maurizio<br>
</p>
<p><br>
</p>
</blockquote>
<br>
</body>
</html>