Ted Kremenek of Apple announced on the Swift evolution announcements mailing list that the team will no longer accept source-breaking changes for Swift 3. That is, changes that would require developers’ own Swift code to change. He notes that this means many desirable features will not make the cut, and will have to be pushed to Swift 3.1 or beyond:
The challenge of course is reconciling these diametrically opposing goals: maintaining source stability while having the ability to incorporate more core (and important) language changes that are possibly source-breaking.
How will they balance this going forward? He hints that the team wants to support a mechanism whereby developers can specify a version of Swift as a parameter to the compiler. Your code builds against Swift 3.1? The Swift 4 compiler will be able to handle that:
Our goal is to allow app developers to combine a mix of Swift modules (e.g., SwiftPM packages), where each module is known to compile with a specific version of the language (module A works with Swift 3, module B works with Swift 3.1, etc.), then combine those modules into a single binary.
This is great news for developers, but only strengthens my argument that Swift needs a mechanism for SDK-conditional compilation. At this point, a developer who wishes to maintain source code that compiles against, say, iOS 9 and iOS 10, must conditionalize on the version of Swift:
#if swift(>=2.3) // iOS 10 only code #else // iOS 9 friendly code #endif
When and if Ted Kremenek’s promise of a multiversioned Swift compiler comes to pass, it will presumably mean multiple versions of Swift can compile against the same SDK, so this fragile workaround will no longer … work.
Update: It occurs to me, multiple versions of Swift already do build against the same SDK. Currently we have Swift 2.3 and Swift 3 building against Apple’s latest beta SDKs. It’s the “>=” in the workaround that guarantees a suitable SDK match for now.