[swift-evolution] Review for: Remove C-style for-loops with conditions and incrementers
Rainer Brockerhoff
rainer at brockerhoff.net
Sat Dec 12 08:41:41 CST 2015
Review of SE-0007
Note: haven't had time to write this up during the week, apologies for
the late comment.
* What is your evaluation of the proposal?
+1 on the proposal, as long as my suggestion below ("repeat" clause) is
also implemented.
I always felt the C-style `for var i = 0; i < n; i += 1 {...}` loop was
an anachronism. A semicolon-separated list of heterogeneous items:
- a declaration and/or initialization;
- a boolean expression;
- a statement which is executed not there, but between loop iterations.
I do remember in the early C days that (some) people delighted in
cramming stuff inside the for header and have an empty loop body. This
was fun, but needlessly obscure/tricky. Enumerating a linked list was a
frequent sample.
Also, for many purposes one had to use tricks, like extra booleans, or a
switch on the index, to special-handle the first or last time through
the loop.
Substituting a `while` loop can be, as many have already pointed out,
seriously problematic when `break`, `continue` and `throw` are used
inside the loop, and `defer` is not a good solution for that, either.
So, I propose that the `while` loop should get an optional `repeat`
clause at the end, like this:
var item = firstItem // declaration/initialization
while item != nil { // condition
if SomeExtraCondition(item) {
break;
}
process(item)
} repeat { // increment
item = NextItemFor(item)
}
Where the statements inside `repeat` are executed after each loop, but
only if the loop will continue. I think this offers the necessary
conceptual clearness and existing for-loops are easily converted
automatically. The eye will skip over the `repeat` clause for the last
iteration as it now does for `else`.
Also, `break`, `continue` and `throw` will all continue to work as expected.
I also propose that the `repeat` clause be extended to the remaining
`for-in` loop:
for item in sequence {
print("\(item)")
} repeat {
print(", ")
}
which will be handy in many situations.
Finally, I think that `for i in 0..<n` is acceptable for counting.
Having reverse ranges would help but is not as frequent.
BTW: `loop` or whatever is felt to be more readable could be used in
place of `repeat`.
* Is the problem being addressed significant enough to warrant a change
to Swift?
Yes, I do think that it will remove a source of errors for programmers
migrating in from C/C++/ObjC, and the "repeat" clause will offer a more
functionality for the loops.
* Does this proposal fit well with the feel and direction of Swift?
Yes.
* If you have you used other languages or libraries with a similar
feature, how do you feel that this proposal compares to those?
I've used C/ObjC extensively for decades, older languages are probably
not useful by now :-)
* How much effort did you put into your review? A glance, a quick
reading, or an in-depth study?
I've read (and now, re-read most comments on this list. I haven't
checked the Swift sources for implementation implications (nor do I feel
yet qualified to do so).
--
Rainer Brockerhoff <rainer at brockerhoff.net>
Belo Horizonte, Brazil
"In the affairs of others even fools are wise
In their own business even sages err."
http://brockerhoff.net/blog/
More information about the swift-evolution
mailing list