Review: SE-0007 (Remove C-style for-loops with conditions and incrementers)


(Alex Chan) #1

1. I strongly support this change.

2. It’s not a problem, but an antipattern. Just as it’s important to add new features, it’s also important to consider what should be removed. The for-loops feel like a piece of legacy baggage; I can’t imagine them being added (at least in this form) if they weren’t already in Swift. I can’t imagine a scenario in which I’d recommend using the C-style for-loop instead of a more expressive Swift construct (and was unable to find a counterexample in my Swift or Python code).

3. This proposal fits nicely with Swift, for a few reasons:

   * Readability. The alternatives tend to more expressive and explicit, and feel more Swift-like.

   * Safety. For-loops are often used to iterate over arrays, but it’s easy to make off-by-one errors that mean you miss elements or try to read off the end of an array. For example:

        for var i = 0; i <= bar.count; i++ {
            print("The \(i)th element in bar is \(bar[i]).")
        }

     It would be harder to make this sort of mistake with for-in loops or similar replacement constructs.

  * Simplicity. In my experience, using explicit iterables results in much simpler code in most cases.

4. My primary programming language is Python (for now). Python has neither ++/-- operators nor C-style for-loops. I’ve never had a problem doing complex iterations or loops – indeed, I find Python to be a very powerful language for iteration. I feel the same will hold true for Swift.

   Python and Swift have similar aims for readability and safety. I don’t recall any suggestions to add these constructs to Python; I believe the same would hold true if these constructs weren’t already in Swift.

5. I read the proposal carefully, looked over the responses in the mailing list, and spent several hours reading through my collection of Swift and Python code to look for any cases where lack of a C-style for-loop was a serious impediment. (I didn’t find any.)

— Alex


(thorsten@portableinnovations.de) #2

1. Evaluation
Initially I was hesitant but now I support this change.
The C-style for-loop is syntactic baggage (the semicolons do not separate its parts very well) and suffers from the problem that it is imperative, i.e. The loop variable is just that, a variable, and therefore will not work as expected when captured in closures that are executed later, e.g. in a GCD queue.
There might be some corner cases where the C-style for-loop cannot be easily replaced with a for-loop or a while-loop in the presence of several continue statements, which is why I originally proposed to Swiftify the C-style for-loop instead of removing it, but I haven't seen a concrete one yet and I am optimistic that good solutions can be found even for these cases by refactorings e.g. extracting the loop body into a function and replacing continue with return. If someone has a concrete case for which that does not apply for some reasons I'd be interested to see that case and reconsider.

2. Significance
The C-style for-loop does not fit syntactically and its use is limited. In most cases the for-in loop is much better suited and more expressive and for the remaining few cases a while-loop can be used.

3. Direction of Swift
This proposal fits the philosophy of Swift with regards to readability and safety because the alternatives are more expressive and readable.

4. Comparisons
I have long experience with mostly Smalltalk, Haskell, Swift and Java, and from earlier times with C, C++, Python and Ruby. Furthermore I follow the development of many languages with modern constructs closely, e.g. Scala, Ceylon, Clojure and others and have a strong interest in programming language design.
Most of these languages, i.e. all except Swift, Java and of course C and C++, do not have a C-style for-loop. They typically do have more expressive loops similar to the for-in loop of Swift (or more powerful, e.g. Scala's for-expression which is similar to Haskells monadic do-notation).
Dylan has an iterating for-loop which improves on the C-style for-loop by introducing a new binding for the loop "variable" on each iteration, which might look like follows in a Swiftified syntax:

for i = 0 then i + 1 while i < limit { ... }
for i = 0 then i + 1 until i == limit { ... }

which effectively introduces a let binding in the init clause scoped to the loop, an expression to replace the binding with for the next iteration and a while or until clause which is checked before each iteration.

I would propose this as an alternative to removing the C-style for-loop if a review makes a convincing case that an incremental loop is still needed.

5. Effort
I read the proposal carefully, read the discussion in the mailing list, checked two large Java codebases (large systems for logistics) for occurences of for-loops and did only find trivial ones. Furthermore I checked textbooks for their looping constructs, e.g. "Concepts, techniques and models of computer programming" by van Roy and Haridi (highly recommended!), .


(thorsten@portableinnovations.de) #3

I would like to revoke my support for the removal of the C-style for-loop because of the following reasons:

Peformance
When doing the review appended below I have neglected to think about performance issues the replacement of C-style for-loops by for-in loops might have. This has not been part of the discussion either, so I am worried that it is not possible to replace C-style for-loops without losing performance or having to use while-loops which might be more verbose especially in the problematic cases with continue and break that have been discussed.

Style
When replacing C-style for-loops by while-loops I fear that bad styles will creep in like the usage of "defer" for the incrementation part of the loop which has been suggested too often in the discussion, even though it has been made already clear by others that "defer" is not appropriate here because of changed semantics in case of break or exceptions.

Therefore I have reconsidered my review and now vote strongly against removal of the C-style for-loop, although I would like to see it replaced by a more Swifty version as proposed as alternative in my review below.

-Thorsten

Anfang der weitergeleiteten E‑Mail:

···

Von: "thorsten@portableinnovations.de" <thorsten@portableinnovations.de>
Datum: 10. Dezember 2015 um 08:22:51 MEZ
An: Swift Evolution <swift-evolution@swift.org>
Betreff: [swift-evolution] Review: SE-0007 (Remove C-style for-loops with conditions and incrementers)

1. Evaluation
Initially I was hesitant but now I support this change.
The C-style for-loop is syntactic baggage (the semicolons do not separate its parts very well) and suffers from the problem that it is imperative, i.e. The loop variable is just that, a variable, and therefore will not work as expected when captured in closures that are executed later, e.g. in a GCD queue.
There might be some corner cases where the C-style for-loop cannot be easily replaced with a for-loop or a while-loop in the presence of several continue statements, which is why I originally proposed to Swiftify the C-style for-loop instead of removing it, but I haven't seen a concrete one yet and I am optimistic that good solutions can be found even for these cases by refactorings e.g. extracting the loop body into a function and replacing continue with return. If someone has a concrete case for which that does not apply for some reasons I'd be interested to see that case and reconsider.

2. Significance
The C-style for-loop does not fit syntactically and its use is limited. In most cases the for-in loop is much better suited and more expressive and for the remaining few cases a while-loop can be used.

3. Direction of Swift
This proposal fits the philosophy of Swift with regards to readability and safety because the alternatives are more expressive and readable.

4. Comparisons
I have long experience with mostly Smalltalk, Haskell, Swift and Java, and from earlier times with C, C++, Python and Ruby. Furthermore I follow the development of many languages with modern constructs closely, e.g. Scala, Ceylon, Clojure and others and have a strong interest in programming language design.
Most of these languages, i.e. all except Swift, Java and of course C and C++, do not have a C-style for-loop. They typically do have more expressive loops similar to the for-in loop of Swift (or more powerful, e.g. Scala's for-expression which is similar to Haskells monadic do-notation).
Dylan has an iterating for-loop which improves on the C-style for-loop by introducing a new binding for the loop "variable" on each iteration, which might look like follows in a Swiftified syntax:

for i = 0 then i + 1 while i < limit { ... }
for i = 0 then i + 1 until i == limit { ... }

which effectively introduces a let binding in the init clause scoped to the loop, an expression to replace the binding with for the next iteration and a while or until clause which is checked before each iteration.

I would propose this as an alternative to removing the C-style for-loop if a review makes a convincing case that an incremental loop is still needed.

5. Effort
I read the proposal carefully, read the discussion in the mailing list, checked two large Java codebases (large systems for logistics) for occurences of for-loops and did only find trivial ones. Furthermore I checked textbooks for their looping constructs, e.g. "Concepts, techniques and models of computer programming" by van Roy and Haridi (highly recommended!), .