[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