Why I Don’t Care About Swift

Swift is a new programming language created by Apple for use on OS X and iOS devices. The programming world is agog. Apple’s fantastic new language apparently solves all their problems, as evidenced, they say, by the fact that some programmer ported Flappy Birds to it in a few hours.

I’ve been around long enough to see languages come and go. Each claimed to solve all the problems introduced by its predecessors, yet each was replaced by a language that solved all its problems. In some cases, the new language surpassed the success of the language it replaced (C++ and Java); in other cases, the new language faded into obscurity (Modula-2 and Ada).

Lately the motivations for new languages have been dubious. There is a big emphasis on making a language easy to learn and having it hide nasty issues related to memory management and type safety. One review of Swift I read stated, “Apple hopes to make the language more approachable, and hence encourage a new group of self-taught programmers”. While that sounds great, it means that those of us who have mastered our craft after 30 years or more of practice are saddled with the training wheels and water wings that are written into these languages for the noobs.

A classic example is the lack of unsigned integers in Java. The motivation for this was to simplify the language for “new and self-taught programmers” by avoiding errors caused by a lack of understanding of sign-extension. However, for those of us who showed up for class the day that sign extension was taught (that would be day two), we’re left with a language that unnecessarily limits the range of positive integers and requires us to actually have mastered sign extension in order to understand what is happening when we directly manipulate the bits in our integer variables.

Explicit vs. Implicit Typing

One of the simplifications Swift makes is that it infers the types of variables from the values assigned to them rather than requiring the programmer to explicitly type variables. If this was true “weak typing” like I’m familiar with in VBScript, it would be great (though it would come with its own set of problems). But all Swift does is infer the type of the variable from the first value you assign to it.

This actually introduces problems, because it’s not always possible to unequivocally determine the type of a literal value. So Swift gives you ways to force it to interpret a literal value as a given type. Rather than removing the necessity of the programmer understanding types, Swift thus requires “new and self-taught” programmers to have a mastery of types so that they can understand how Swift is working behind the scenes and make sure that their variables have the desired type.

Strings

Swift is said to improve string-handling over Objective-C (the current language used on OS X and iOS). There is certainly room for improvement there. When I first started programming in Objective-C, one of the first things I did was bring over my own C++ string class, as I found NSString to be overly complicated and muddled. Over the years I’ve gotten better with NSString.

I would argue, however, that some of the so-called “improvements” in Swift with respect to strings are differences without a distinction. So instead of this in Objective-C:

[NSString stringWithFormat:@"The value of num is %d", num]

you say this in Swift:

"The value of num is \(num)"

The Swift version is obviously more concise, but it is also less powerful. To add more complex format specifications to Swift you actually have to invoke the functionality of the underlying NSString class, which means the “new and self-taught” programmer, again, needs to understand the details of the implementation in order to do anything beyond the simplest strings.

One of the stated benefits of string handling in Swift is that “all strings are mutable”. One need not worry about whether the string is declared as an NSString (immutable) or NSMutableString (mutable). Well, you don’t have to worry unless you do have to worry — strings assigned to constants are immutable in Swift. So:

var myString1 = "Mutable string"
let myString2 = "Immutable string"
myString1 += myString2    // perfectly legal
myString2 += myString1    // compile-time error

Switch Statements

Swift eliminates the “fall-through” behavior of switch statements, which is said to eliminate bugs caused by omitting the break at the end of each case block. But, oops, sometimes the fall-through behavior is exactly what you want. So Swift adds the fallthrough keyword. It could be argued that Swift eliminates a line of code (the break) while giving the behavior one normally desires. But at the same time, it adds a keyword (fallthrough) that does the opposite. This requires “new and self-taught” programmers to have the same thorough understanding of switch behavior that Objective-C and C++ programmers do.

Single-line Blocks

The Swift compiler will warn you if you omit the braces in any block (such as after an if) and does not allow single-line blocks, thus avoiding this error:

if (x < 0)
    goto fail;
    goto fail;

The code above will always execute one or the other of the goto statements in Objective-C or C++. Even though the second goto is indented, it is not part of the if-block and will be executed if the condition is false.

Swift will warn you about the missing braces and force you to write this:

if (x < 0)
    {
    goto fail;
    }
goto fail;

Or, for those of you who don’t do your braces the right way, this…

if (x < 0) {
   goto fail;
}
goto fail;

This is fine, and hard to argue with. The supposition is that the programmer will immediately recognize the flaw or won’t make the mistake in the first place. On the other hand, I would argue that the same C++ programmer who wrote the erroneous code will write this in Swift:

if (x < 0) {
    goto fail; }
    goto fail;

I always put braces around my blocks, even if they are one-line, so this doesn’t affect me. It’s ironic, however, that while Swift prides itself in eliminating the unnecessary break statement at the end of a case block, it requires two to four additional lines (braces) in if, for, and while statements, which are more numerous.

PocketBible and Swift

I will be more than happy to learn and use Swift for programming on iOS and OS X. I just don’t believe the hype and won’t convert just for the sake of doing something new.

I am a strong proponent of platform-independent languages like C, C++, Java, and, to a lesser extent, Objective-C (the latter is primarily an Apple language, though it has its origins outside of Apple). Such languages allow me to develop code on one platform and re-use it on another. One of the promises of C++ and Java was that you could develop the code for one platform and use it on many others. Swift is an Apple language (the same way C# is a Microsoft language). It only works on Apple devices. While those are numerous, they’re not the only devices out there. So rather than moving toward the “write once, read everywhere” model promised by Java, we’re back to “write everywhere” as each platform requires its own language.

I don’t mind learning a new language. I already jump from C++ to C# to Java to VBScript to Javascript to MS-SQL on a daily basis. For those of us who write code for a living, being multilingual is a job requirement. This is precisely why I care so very little about the supposed advantages of Swift; this isn’t a religious war for me, it’s just a tool. When someone comes out with a new kind of screwdriver, I may or may not buy it until I need it. And then I’ll just buy one and use it — I won’t try to convert all my screwdriver-toting friends.

So will PocketBible for OS X and/or iOS be re-written in Swift? Probably not today, and probably not until Apple requires it. But Swift depends on Objective-C under the hood, so my guess is that Apple will continue to support Objective-C apps for a long time.

2 thoughts on “Why I Don’t Care About Swift”

  1. I know this is an older post but I think your arguments against swift are weak in this post – don’t get me wrong there are plenty of reasons not to care about swift but I don’t think these are the right ones.

    The reason swift removes the break is not for the sake of saving lines or keystrokes as you reason and call ironic. It is bringing logical consistency to case ‘blocks’. Because in no other context is the next block run. There are no fallthrough if statements. I think it is a purely historical feature that switch fallsthrough by default and making fallthrough explicit is a step in the right direction and still allows switch statements to do it.

    I completely disagree about the string manipulation point. It makes string formats easier and simpler. Yes if you want to format it you need to do that anyway, which you would have to do in the NSString version. So I am not even sure what you are saying. It simply makes putting a variable in a string easier. It says nothing else about NSString. It also adds a new type ‘String’ which may be what you mean which does try to replace a lot of the NSString features and hopefully will expand as swift does.

    I agree that weak typing is a step in the wrong direction – strong typing is safer while weak typing can help newbies learn (and is easier for prototyping/playground settings). So I am little torn on it, but vote for strong typing.

    1. Thanks for the comment, Jordan.

      It could be argued that there is no qualitative difference between break and fallthrough. That is, it is either the case that execution in the switch statement will normally fall through the end of one case into the next (and therefore break is a needed feature) or it is the case that execution will normally stop at the end of a case block (and therefore the fallthrough statement is needed). The language designer’s argument is essentially what you said: Since you don’t fall from the if block into the else block, then it is reasonable to think that programmers (especially the new and self-taught programmers that Swift is apparently designed for) will not expect case blocks to fall into each other. But this belies a misunderstanding of what the switch statement is. It is a way of jumping to a label based on a value. It comes from C, which was attempting to bring a low level construct (an assembly language “jump table”) into a high level, structured language. case labels are not required to be followed by blocks, but simply by a sequence of statements. The fall-through behavior mimics the construct from which it was derived: there are no blocks in assembly language, and labels are irrelevant to execution path. If you jump to a label, you will execute right past any subsequent labels until you run into another jump — or in this case, a break statement.

      So it is not the case that execution falls through from case to case accidentally. The whole point of the switch statement is to behave that way. And we all make use of it when we put multiple case statements in a row — the top case falls through its empty block of code into the next case until it finds code ot execute.

      Because the switch statement is intentionally designed to work this way, it is necessary to implement a simple way to escape when necessary; hence the need for break.

      Swift designers arbitrarily decided that C/C++/Objective-C switch statements were “misbehaving”. Or, to put it more accurately, Swift designers were ignorant of how switch statements were designed to work, since they were designed before Swift designers were born, and we all know that nothing that happened before we were born is relevant. 🙂

      In the end, if we ignore my historically accurate description of how switch statements work, we could argue that there is no objective difference between switch/case/break and switch/case/fallthrough. But the Swift designers did this ostensibly to make things easier for new and self-taught programmers. So one has to ask whether it is more “intuitive” to require break to not fall through, or require fallthrough to not break. The argument in my article is that since execution normally flows from statement to statement, requiring a programmer to know that execution jumps out of the switch when the next case statement is reached is qualitatively no different than requiring the programmer to know that it doesn’t. In both cases it has to be explained.

      The designers weren’t setting out to eliminate lines of code, they were setting out to make it easier. My argument is that it isn’t objectively easier either way. So the follow-up is, why change the way we’ve been writing switch statements for 40+ years just so you can pretend you’re making it “better”?

      My point about strings is while certain strings can be easily constructed using the built-in capabilities of Swift strings (such as the example given in the post), as soon as you want to control the number of significant digits, leading or trailing zeros, etc., you get into having to learn standard C format specifiers. Since this is fairly common in a lot of cases, the new and self-taught programmer still has to understand how to initialize a string using the equivalent of Objective-C’s stringWithFormat: anyway, so nothing gained.

      This having all been said, in today’s app economy, we are all forced to go where the “new and self-taught” programmers that make up Apple’s language design team take us. So we are left to vent in personal blogs in quiet corners of the Web. 🙂

Leave a Reply

Your email address will not be published.