Swift's Progress Toward Stability
The Swift language offers many wonderful features, but one area where it's had a mixed record is stability. Apple has promised a stable ABI (application binary interface) since its early announcements for Swift 3, but at version 4.1 it still isn't there. It's now expected in Swift 5, sometime in 2018. Stability at the source level has greatly improved, though.
What is ABI stability?
The ABI of a compiled language like Swift is the details of how one piece of code calls another. It depends on the calling conventions and the data formats which the compiler uses. Not all languages define an ABI. Perl, prior to version 6, was a purely interpreted language, so the issue of binaries didn’t come up. C defines the behavior of the language only at the source code level, so different compilers often generate incompatible code.
The possibility of ABI compatibility requires some assumptions about the language and what its definition includes. It requires defining the language’s behavior not just at the semantic level, but at the binary level. Swift provides this definition, but it hasn’t locked it in for future versions yet. Version 4 isn’t ABI-compatible with earlier versions.
The Swift ABI Stability Manifesto talks about what ABI stability means for Swift. It’s on a per-platform basis. You’ll never be able to mix modules compiled for an iPhone and a Mac, at least until Apple completely revamps and merges their architectures. Swift compiles to native code, which means using different instructions and making different OS calls. This is different from languages like Java, which runs on a virtual machine and uses the same ABI on every platform.
However, Swift uses an LLVM compiler, which generates machine-independent bytecodes that are then compiled to platform-specific code. It’s likely that Apple is aiming at full ABI compatibility at the LLVM level.
Currently, the only compiler anyone uses in production is Apple’s. The language is open-source, so someone else could develop an independent compiles, but it will need to satisfy the binary definitions as well as the syntax and semantics to be a correct implementation. If any compiler does this, though, it should be easy to mix its object code with code generated by the Apple compiler.What are the benefits?
So far, each version of Swift has had an incompatible standard library and runtime. This means that each application has to include its own copy of them, since applications built with different versions must coexist. If Swift 5 has a standard ABI, all applications built with version 5 or later will be able to share the same libraries. Applications will be much smaller.
This isn’t sufficient for version-independent frameworks, though. Apple is pursuing a second goal, module compatibility. It will define a standard format for module files. Currently it’s somewhere in the indefinite future.
ABI compatibility is an aspect of what Apple calls “abstraction of implementation.” The idea is that code libraries should remain compatible at the binary level, even if their underlying code or the compiler version changes.
New versions of a language will, of course, have new features. Libraries will have new functions, and data structures may have new fields. The point of compatibility isn’t to freeze the language but to keep things from breaking. Swift includes the #available check to determine if a needed library version is present, and the code can provide fallback behavior when it isn’t.Swift’s progress on stability
At one time, Apple said it would establish ABI stability in Swift 3. That turned out to be harder than expected, so it didn’t happen. Part of the problem was moving away from the legacy of the ABIs of Objective-C and Cocoa. There’s no indication yet that Apple plans to drop Objective-C interoperability, so it continues to complicate the issue.
Swift 3 wasn’t even compatible at the source code level. There were significant changes from Swift 2 in the syntax of function calls, so a lot of code had to be rewritten. Swift 4 requires some source changes from version 3, but the transition wasn’t nearly as bad as the one to Swift 3. The compiler offers a compatibility mode for Swift 3 source code, and frameworks compiled as Swift 3 are interoperable with ones in Swift 4.
Most of the latest changes are in specific language features rather than affecting everything. One of the more significant differences is that a feature called “@objc inference” is deprecated. In Swift 3, some declarations automatically generated entry points allowing calls from Objective-C. In Swift 4, code that uses inference will generate compiler warnings. It may be necessary to change the compiler settings or add @objc annotations to compile cleanly. This change reduces the amount of unnecessary legacy object code.
ABI stability, promised again in Swift 4, is postponed again. Actually, version 4 has made considerable progress toward it. In a language as complex as Swift, there are many things that need to be done before the ABI can be locked down.What’s in the future?
Apple is now saying that ABI compatibility will come with Swift 5, in late 2018. Once it arrives, Apple expects it will “persist for the rest of the platform’s lifetime due to ever-increasing mutual dependencies.” In this case, inertia is your friend. Module stability, allowing compatibility with older frameworks, is a “stretch goal.”
With a stabilized ABI, Apple will doubtless include a Swift runtime library in MacOS and iOS, so that new applications will be able to call it instead of including their own copy. That will save megabytes in each application. Older apps that upgrade to Swift 5 will benefit as well.
Swift has come a long way in a short time. The language isn’t even four years old yet. It’s already replaced Objective-C for most new Apple application development. Developers who felt burned by the changes in Swift 3 should be encouraged by the much smaller amount of code-breaking changes in version 4.
To really be a top-ranking programming language, Swift needs to move beyond Apple platforms. The prospect of source and binary stability is already helping. Vapor developers are reporting that few code changes are needed to migrate to the new version.
Once it has slimmer applications and version-independent frameworks, it will be more useful than ever.
We’re always keeping our eye out for software development tools that will help us serve you better. Contact us to talk about the software development project you’re thinking of.