Is Swift Programming Ready for Prime Time?

The recent unveiling of Swift (http://techcrunch.com/2014/06/02/apple-launches-swift-a-new-programming-language-for-writing-ios-and-os-x-apps/), Apple’s new programming language for crafting [iOS applications, sent ripples of excitement through the iOS development world.

Since its introduction, many iOS developers have been grappling with the decision of whether, when, and how to make the shift from Objective-C to Swift. The ideal answer to this dilemma will naturally vary depending on the team and the specific project.

Countless articles delve into the numerous advantages of Swift surrounding this transition. Instead of reiterating those points, this piece will instead focus on a few considerations you might want to ponder before taking the plunge into Swift app development.

Programming with Swift may or may not be ready for primetime - have you learned the Swift language yet?

Let’s rewind the clock a bit first…

The Pre-Swift Era: Objective-C or Bust

The year was 2010. The iPhone was still in its infancy, not even three years old, and the ability to create native iPhone applications was a mere two years old. On April 8th, Apple announced a pivotal update: iPhone OS 4. This version, later rebranded as iOS, promised alluring new features like multitasking, swift app switching, and background services. Developers were understandably eager to explore the new SDK and harness these exciting capabilities.

However, the iPhone OS 4 SDK delivered an unexpected curveball. This time, the surprise wasn’t in the software itself but in the accompanying usage agreement. Section 3.3.1 of the Developer Agreement had been updated to include this concerning statement:

Applications must be originally written in Objective-C, C, C++ … and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs. – Section 3.3.1 of the iPhone OS 4 SDK Developer Agreement

Understandably, this restriction took many developers by surprise. The official rationale for the change, provided by Steve Jobs himself, was to curtail the use of cross-platform tools like the recently launched Flash CS5. Steve Jobs famously stated that “intermediate layers between the platform and the developer ultimately produces [sic] sub-standard apps.” However, Apple’s tactic of restricting programming languages to combat these “intermediate layers” revealed a deeper sentiment: Objective-C should suffice for everyone.

This assertion wasn’t entirely unfounded, as Objective-C clinched the Tiobe Index’s “Programming Language of the Year” award that very year (two years in a row). The reality, however, was that Objective-C’s popularity stemmed from the burgeoning app ecosystem, not the other way around. Even back in 2010, dissatisfaction with Objective-C was brewing, and alternative methods for creating iPhone apps (in other programming languages were already surfacing.

Facing pressure from the wider developer community, Apple eventually rescinded these changes to Section 3.3.1 the restrictive clause from the SDK Developer Agreement a mere five months later. The message, though, was clear: Objective-C was the preferred route for iPhone app development.

A New Era Dawns: Swift Enters the Scene

Fast forward four years to June 2014. Apple introduced Swift (Swift), its brand-new programming language. If the message four years prior implied unwavering faith in Objective-C, Swift’s arrival signaled a shift. Apple seemed ready to acknowledge that Objective-C might not be the ultimate language for mobile app creation.

Swift has been lauded as a more “modern” language than Objective-C. For those curious about mastering Swift, resources like the “Moving from Objective-C to Swift” guide offer valuable insights.

Importantly, Swift diverges from Objective-C in two significant ways:

  1. Swift is not a strict superset of C.
  2. Swift is statically, not dynamically, typed.

Not being confined to C’s syntax allows Swift to utilize constructs that would otherwise be off-limits. This freedom, for example, allows for innovative features like custom operators.

As a statically typed language, Swift can leverage advancements in type systems pioneered by languages like Haskell.

Despite undergoing a period of in development for 4 years before its public debut, Swift remains a young language, which comes with its own set of caveats.

Bridging the Gap: Compatibility with Objective-C

iOS shares a lineage with OS X, which, in turn, traces its roots back to the NeXTSTEP operating system first launched in 1989. NeXTSTEP was primarily written in Objective-C, and many core libraries in OS X and iOS still carry echoes of these original implementations. (This explains the ubiquitous “NS” prefix found in core classes like NSString.) While Swift could theoretically function independently of these libraries, the reality is that any Swift code written in the foreseeable future will need to interact with Objective-C.

The Swift developers deserve credit for making interaction with existing Objective-C libraries relatively smooth. However, some friction points remain. Apple provides a helpful guide to guide developers on calling Objective-C code from Swift, and vice versa. Yet, some significant impedance mismatches require attention.

The most evident mismatch lies in header files. Due to its C heritage, Objective-C mandates function declarations before their use. When interacting with a library, these declarations reside in header files. Swift, however, dispenses with header files. Consequently, calling Swift code from Objective-C necessitates the creation of a “bridging header.” While conceptually straightforward, this process can become surprisingly quite the task in practice.

Further complications arise from the inherent differences in their type systems. Taking inspiration from modern languages, Swift has abandoned the concept of nil, replacing it with optional types. For instance, a method designed to open an existing file would return File? (instead of just File) in Swift. By diligently tracking optional types, the Swift compiler effectively eliminates the dreaded “Null Pointer Error” — unless, of course, Objective-C is involved. Since Objective-C doesn’t guarantee the absence of nil, Swift introduces Implicitly Unwrapped Optionals when interacting with Objective-C code. These types can function as optionals within Swift, with the accompanying overhead of existence checks. Alternatively, they can behave like non-optional types, but if Objective-C returns nil, a runtime error occurs, sacrificing some of Swift’s compile-time safety.

A final, subtler mismatch to consider concerns how these languages handle object and class creation. Objective-C, being dynamic, uses dynamic dispatch to invoke object methods (via objc_msgSend). Swift, while capable of dynamic dispatch, can also leverage its static typing to employ a vtable for storing method function pointers. The chosen mechanism depends on various factors. Plain Old Swift Objects utilize the vtable approach unless annotated with Swift’s @objc attribute. Swift subclasses of Objective-C classes use dynamic dispatch for inherited methods but not for newly introduced ones (again, the @objc attribute can enforce dynamic dispatch). Essentially, Swift code seamlessly interacts with Swift classes, but Objective-C code can only utilize appropriately annotated Swift objects and methods.

Outpacing Objective-C: A Question of Speed

When Apple first unveiled Swift, speed was touted as one of its key advantages. This emphasis made sense considering that one reason often cited for clinging to Objective-C was its C-based efficiency, supposedly capable of generating faster programs than languages like Python or Ruby.

However, even Objective-C isn’t lightning fast, partly due to its dynamic typing. With its static type system, Swift was expected to match or even surpass Objective-C’s performance.

As the adage goes (saying goes), “There are three types of lies: lies, damned lies, and benchmarks.” There are undoubtedly areas where the Swift language might excel in speed (numerous reasons why). However, Swift’s implementation of Apple’s ARC (Automatic Reference Counting) memory management technique seems to sometimes result in significantly slower code generation, particularly with lower optimization settings used during development. The silver lining is that Swift is continuously being refined (continually addressing this issue), so it’s likely that it will eventually generate executables at least as fast, if not faster, than Objective-C.

The speed discussion involves another layer of complexity. The entire premise of Swift is to enable developers to write code differently than they would in Objective-C. How does this impact performance? It implies that comparing Swift and Objective-C performance goes beyond simple benchmarks (more involved). The absolute runtime performance of generated executables is only part of the story.

While fast programs are always desirable, development speed often holds equal or even greater importance. An expressive language, capable of achieving more with less code, can significantly boost productivity. However, in a compiled language where the edit-compile-run-debug cycle dominates a programmer’s workflow, a sluggish compiler can be a major hindrance (hurt productivity). Anecdotal evidence suggests that the Swift compiler, particularly when handling code that utilizes its advanced type system, can be frustratingly slow. One group even found compilation speed troublesome enough to warrant a switch back (back to Objective-C).

The Swift Compiler: A Work in Progress

The Swift compiler itself presents further considerations when contemplating the transition. Apart from compilation speed, as Swift has moved beyond Apple’s internal development circles and into the hands of a broader community, its compiler has revealed some vulnerabilities. There’s even a dedicated online repository (GitHub repository) for documenting code snippets that cause the Swift compiler to crash.

The future of the Swift compiler also raises questions. Another online resource (project on GitHub) serves as a hub for community speculation and analysis regarding potential changes to Swift. For example, custom operators can strain a parser. Initially, Swift’s custom operators couldn’t use question marks (?). While this limitation has been addressed in the latest release, the expanding Swift community continues to request clarification and adjustments (even more flexibility) regarding valid custom operators.

Any hint of a language’s parser being in flux should give developers pause. A language’s parser is its bedrock, defining what constitutes valid code before semantics even come into play. It’s encouraging that Apple has pledged efforts (promised) to maintain a degree of runtime compatibility for Swift. However, this doesn’t guarantee that Swift code will run flawlessly across different Xcode or iOS releases without recompilation. It also doesn’t guarantee that code won’t require rewriting to stay compatible with future Swift versions. Apple’s commitment to minimizing disruption provides some comfort, at least.

The Swift Community: A Work in Progress

Some of the most poorly designed programming languages in existence (names withheld to protect the guilty) have managed to cling to life, long past their expiration date, solely due to the strength of their communities. Conversely, many excellent languages have withered and faded due to a lack of community support. Thriving communities foster learning through tutorials, provide answers on forums like Stack Overflow, connect online and at conferences, and contribute to a shared pool of knowledge and resources, including open-source libraries. When selecting a language, the strength and vibrancy of its community shouldn’t be overlooked.

Unfortunately, the iOS/Objective-C community hasn’t always been known (does not have the best reputation) for its openness and inclusivity. This is gradually changing, and open-source practices are gaining traction (playing a more important role) within Objective-C development. However, it’s still early days for Swift, making it difficult to predict the trajectory of its community. Will it primarily consist of insular developers relying solely on official Apple APIs and their private codebases? Or will it blossom into a vibrant ecosystem where knowledge, code, and best practices are freely shared?

Another aspect of community involvement relates to the role of Swift’s developers themselves. The broader programming landscape shows a clear shift towards open-source languages and platforms over proprietary ones. Open-source development, especially for languages and runtimes, offers inherent advantages. While the Swift developers have stated their intention to fully open-source the language and runtime, this is yet to happen, so some caution is warranted.

It’s worth noting that the minds behind Swift also brought us the long-standing LLVM project. While not a perfect analogy, as LLVM originated as an open-source project at the University of Illinois Urbana-Champaign, the core LLVM developers have maintained an open and collaborative approach (engaging with the community), even after most transitioned to Apple. It’s reasonable to anticipate that Swift’s development will continue in a relatively open manner. However, the extent to which community contributions and feedback will shape the language’s evolution remains to be seen.

The Verdict: Should You Learn Swift?

There’s no single right answer. As with any tool, choosing the optimal language for iOS development hinges on the project’s specific needs and constraints. Currently, Objective-C remains the “safe” choice, but Swift is undeniably worth considering.

Perhaps the most significant shift that Swift introduces to iOS development is that developers are now compelled to ask, “What language should I use?” Given the historical context of Apple, Objective-C, and iOS, this is a significant development. Moreover, the choice isn’t limited to just these two. While Apple has made its preference clear, the iOS development community has been diligently exploring and expanding the possibilities.

Licensed under CC BY-NC-SA 4.0