Introduction
Swift is a C-family language, which means that it shares familiar syntax with other languages in that family, notably C itself. This is beneficial because it helps make Swift more accessible. Programmers who are used to working with C-family languages can generally learn new ones quite easily, and we want Swift to be easy to learn.
Motivation
To improve Swift, we should further enhance its similarities to C. Doing so will increase its familiarity to experienced programmers, which makes Swift easier to adopt for widespread use. To achieve this benefit, Swift should introduce certain idioms and operators which are available in C.
Proposed solution
Foremost and obviously, C programmers frequently use the “++
” and “--
” operators, as well as the three-part for
loop with semicolons. The behaviors of these items are well known, and their implementations already exist in the history of the Swift repository, thus restoring them should be easy.
Furthermore, to achieve even greater similarity between the two languages, we propose adding the following constructs from C into Swift:
Inverted offset indexing
In C, not only can an array be indexed with an integer, but also an integer can be indexed with an array: 0[x]
is the same as x[0]
. This is simple and straightforward to implement in Swift, and we can do so in a generic, type-safe, and protocol-oriented fashion.
Of course, C uses integer offsets when indexing, whereas Swift has a more complex index model. Rather than introduce two spellings for the same thing, we propose that the inverted indexing syntax should replicate the C behavior, and thereby address the common request for offset-indexing in Swift:
extension Int {
subscript<C: Collection> (x: C) -> C.Element {
return x[x.index(x.startIndex, offsetBy: self)]
}
}
Anyone coming to Swift from C who has made use of this reversed-index syntax will rejoice, as will anyone who wants “1[x]
” to produce the second element of x
. As a future direction, we can add a similar subscript to ranges, thus allowing “(4...7)["Hello world"]
”.
Down-to loops
C-style for
loops can be written like this:
for(int i = 5; i --> 0;)
As is abundantly clear from this intuitive syntax, the loop will be performed with i
equal to each integer from 4 down to and including 0. The Swift equivalent can be even more elegant, allowing us to write “for i in 5 --> 0
”. All we need is an operator to form a reversed range:
infix operator --> : RangeFormationPrecedence
func --> <T: Comparable> (lhs: T, rhs: T) -> ReversedCollection<Range<T>> {
return (rhs ..< lhs).reversed()
}
This turns the compound pseudo-operator “-->
” from C into a full-fledged first-class “down-to” operator in Swift. In keeping with C, it is only used for descending ranges which include the lower bound and omit the upper bound. As a future direction, we can also add the “up-to” operator “++<
” that we all know and love, to form ranges which are open at the bottom and closed at the top.
Negation assignment
Who among us has not, when coding in C, mistakenly typed “=!
” instead of “!=
”, only to have the program compile without error, resulting in unintended behavior that subsequently manifests as a subtle and difficult to troubleshoot bug, which quite possibly isn’t detected until after the product has shipped?
Such fond memories!
We can make C afficianados feel right at home by bringing this all-too-familiar experience to Swift with a negation-assignment operator. To replicate the behavior of C, we propose adding the following:
infix operator =! : AssignmentPrecedence
func =! (lhs: inout Bool, rhs: Bool) -> Bool {
lhs = !rhs
return !rhs
}
func =! <T: Numeric> (lhs: inout T, rhs: T) -> Bool {
lhs = (rhs == 0) ? 1 : 0
return rhs == 0
}
An alternative implementation would directly inspect the bytes of any type at all, performing the implicit C-style conversion from raw memory to a boolean value. We leave that enhancement for a future follow-on proposal.
Conclusion
Making Swift more familiar to C programmers is a worthwhile goal, because it helps promote the widespread use and adoption of Swift. To improve the language in this area, we propose the addition of certain operators and functionalities that will make Swift more similar to C.
Specifically, we want new Swift programmers to be able to make exactly the same mistakes and bad design decisions that they are familiar with from C, ideally with very subtly different edge cases and pitfalls. We think this will improve the language.