Why you shouldn’t mourn the removal of –, ++ and C-style for loops from Swift

One of the neatest things about Swift going open-source earlier this year is that the deliberation process for the future of the language, including breaking changes to the syntax, is out in the open. Case in point are the two accepted proposals to remove the unary -- and ++ operators and to remove C-style for loops.

The case against — and ++

View the proposal.

Chris Lattner, the principle architect of Swift, has stated in the past that the ++ and -- operators were added very early in Swift’s inception simply because Objective-C had them. Now that Swift has had a chance to mature, there are a few factors which indicate they are a poor fit for the language. First and foremost is that they are confusing as hell to programmers who haven’t already spent time banging their heads against them in one of the C-derived programming languages. Consider this case:

[gist https://gist.github.com/JoshuaSullivan/72cfabb9ac63aa2721d5 file=”IncrementDecrementExample.swift” /]

The trailing versions of these operators are particularly confusing, where the value is being returned prior to being changed. This difference in pre- and post-incrimenting of the variable is a particularly fruitful source of errors in code, with things like index values going out of range or holding unexpected values because the wrong operator was used.

The strongest case for keeping them is their brevity, but Swift does not favor brevity over security and, as Chris Lattner points out, the more expressive n += 1 is hardly an onerous amount of typing. The main use for the operators seems to be in C-style for loops (based on a survey of Swift-based GitHub projects). Thus, with the imminent removal of those for loops from the language, the main use-case for the operators will die with them.

The case against C-style for loops

View the proposal.

The C-style for loop, like the unary increment and decrement operators, were added early in Swift’s development simply because Objective-C had them. As Erica Sadun so eloquently points out in her proposal, they’re a hold-over from an earlier era of programming and have a complex and error-prone syntax. They accomplish nothing which can’t be accomplished in a more succinct and expressive fashion using the Swift for in loop. Consider these two examples, both of which combine strings from an array to a base string and prints them out:

C-style for loop
[gist https://gist.github.com/JoshuaSullivan/72cfabb9ac63aa2721d5 file=”CForLoopExample.swift” /]

Note that the for loop syntax is completely non-expressive. There’s no indication of what each of the “;”-separated fields aims to accomplish…you have to already be familiar with it.

Swift map() function
[gist https://gist.github.com/JoshuaSullivan/72cfabb9ac63aa2721d5 file=”MapExample.swift” /]

“But wait,” you might say, “I need the index value as well!” There are a couple of ways to do it in Swift without relying on C-style for loops:

Method 1: enumerate()
The handy enumerate() method is present on all collections conforming to SequenceType is one way:
[gist https://gist.github.com/JoshuaSullivan/72cfabb9ac63aa2721d5 file=”EnumerateExample.swift” /]

Method 2: for-in over a Range
[gist https://gist.github.com/JoshuaSullivan/72cfabb9ac63aa2721d5 file=”IterateRangeExample.swift” /]

The 2nd method is stylistically closest to the C-style for loop, but it is still much easier to understand what values i will hold and isn’t subject the problem of a statement inside the for loop modifying the index and causing it to go out of bounds (i is constant).

Conclusion

It can feel a little jarring to lose language features, but with some thought it is clear to see that the removal of these 2 features will result in a language that is more expressive and less error prone.