写于 2017 年 2 月 14 日
作者：Jeff Johnson, Underpass 开发者
我一直在问自己—— 苹果对于 Swift 及 Objective-C 这两种语言究竟有着怎样的规划？当 2014 年 Swift 面世时，它的创始人 Chris Lattner 似乎宣称 Swift 和 Objective-C 将无限期地共存。从下面的 Xcode 拥趸的邮件列表可以一窥：
> 2014 年 6 月 3 日，上午 5:45 分，McLaughlin, Michael P. <mpm...@mitre.org> 写道：
> 有谁知道，苹果是否真的打算停止对于 C 和 C++的支持？
> 似乎会是这样，他们已经不再支持 Fortran 了。
> there is a *lot* of Fortran code out there, even fairly new code like MultiNest.
> Please say it isn’t so. Not all of us consider “power users” to be just those > who create feature-length cartoons. Many are scientists and engineers.
Hi Michael，我们并没有任何类似的计划。Swift 对于基于苹果系统开发来说是一个全新的选择，我们并没有弃 C、C++ 或 Objective-C 而去的计划。如果您使用他们颇感愉悦，请继续毫无顾忌地使用吧。
The problem is that nobody believes this. And of course Lattner has now left Apple, so he won't be there to take the criticism if his claim turns out to be false. The consensus among developers is that Apple will eventually deprecate Objective-C, and Swift will become the sole first class language for Cocoa app development. The qualifier "first class" is important here, because there's no reason for Apple to deprecate or remove compiler support for Objective-C. The compiler supports many programming languages, some of them very old and little used. So Lattner's claim could be true based on a technicality, but that's not what everyone cares about. They care about using the language to make Cocoa apps on iOS and macOS.
The developer consensus is probably right. I agree with the consensus that Objective-C and Swift cannot continue to coexist indefinitely. However, I'm not as confident as other developers that Swift is the future. The consensus is probably right, but what if it's wrong? That's the possibility I want to explore in this article. First, though, let me talk about why Swift and Objective-C can't peacefully coexist indefinitely.
A New Hope?
Neither Swift nor Objective-C is used much for development outside of Apple platforms. That may change in the future, but for now it's the fact. So if you want to write apps on Apple platforms, you have to learn one or the other, or both. The question for new developers is, which language do you learn? If you learn only one language, the standard advice would be to learn Swift. Although I don't necessarily agree with the standard advice, I do agree that it is the standard advice. Wiser heads suggest that you should learn both Objective-C and Swift. But therein lies a problem. If you have to learn two new, platform-specific programming languages just to write apps, that makes Apple platforms a lot less attractive to developers. Swift is reputed to be attractive to new developers because it is more "modern" and "familiar" than Objective-C. But if you have to learn Objective-C anyway, then where's the advantage?
Third-party developers have adopted Swift, um … swiftly. When Apple said jump, they jumped. Like Apollonia into "Lake Minnetonka". Swift has become very popular, very swi… let's just say fast. This has generated a tremendous demand for Swift resources. On mailing lists, forums, blogs, Stack Overflow, Twitter, everywhere developers want to know about and talk about Swift. Swift has affected the technical book publishing industry. It's even affected the job market. A lot of companies now, whether rationally or out of ignorance and trendiness, hire only Swift developers. Many new developers to Apple platforms don't know any Objective-C. And many former Objective-C developers now use Swift exclusively, to the point where they forget Objective-C and have trouble when they need to read or write it. The enthusiasm and demand for Swift among developers threatens to drown out Objective-C. The two languages may coexist "officially" in Apple's mind, but can they coexist unofficially in everyone else's mind? Can there be dual language stacks in every email, blog post, and wiki page? What about open source projects? Will they be Objective-C or Swift? And if the job market moves almost exclusively to Swift, developers may have no choice but to go in that direction.
The Empire Strikes Back
The argument so far suggests that Objective-C is doomed. Swift is starting to dominate with third-party developers. Yet all is not lost, because third-party developers do not rule Apple platforms. The one place where Swift has not begun to dominate is, ironically, within Apple itself. Apple has been very slow to adopt Swift. To this point, Apple has shipped shockingly little Swift code. A nice analysis of this subject can be found in a recent blog post. Several explanations — some might call them excuses — have been proposed to explain this lacuna. For example, Apple frameworks cannot use Swift because it has not yet achieved ABI stability. (Or even source stability, for that matter.) However you want to explain it, the fact remains that Apple's internal Swift code base is relatively tiny. Whereas Apple most likely has the largest extant Objective-C code base in the world.
If Apple had to deprecate one of the two languages today, which would they deprecate? Deprecating Swift would be enormously painful for third-party developers. For Apple itself, on the other hand, deprecating Swift would be relatively painless. They would have very little code to convert from Swift into Objective-C. To be sure, Apple has put a lot of effort into Swift, especially with regard to Xcode. However, those are sunk costs. If Apple is rational, they shouldn't throw good money after bad. Apple has also put a lot of effort into Objective-C, especially with regard to Xcode, and those are also sunk costs, just sunk further in the past than the Swift costs. What matters is not the price already paid but the price to be paid in the future. Apple is not adverse to writing off sunk costs. According to rumors, they've invested a ton of money into an automobile project with nothing to show for it, and that project has reportedly been shelved for the most part.
Apple could convert its entire Objective-C code base to Swift if they wanted. They certainly have the resources. The amount of liquid assets they own is staggering, of a size unprecedented in history. Nevertheless, their current corporate culture suggests they cannot or will not perform this conversion. A number of factors stand in the way. First, Apple has moved to a yearly release cycle for all of their major OS versions. Indeed, reports are that they've bought into the "Agile" software development philosophy. This leaves little room or time for complete rewrites. And we've seen how quality tends to decline and features tend to get lost when Apple rewrites an app or a technology from scratch.
Second, Apple prides itself on only hiring the "best" engineers. I know a lot of engineers both inside and outside of Apple, and I consider this to be a myth, but regardless of whether it's true, this is truly what Apple believes, and thus they are unlikely to make a massive number of new hires and throw a lot of bodies at the problem of rewriting Objective-C code.
Third, related to my earlier points, the availability of Objective-C engineers is in decline. Even if Apple wanted to throw a lot of bodies at the problem, where would they find the bodies? If you want to convert an Objective-C code base to Swift, you surely need engineers who understand both. Trying to rewrite an Objective-C code base in Swift with engineers who don't even know Objective-C would be a recipe for disaster.
The Apple internal calculus indicates that if the Sophie's Choice had to be made today to axe one language, Swift would have to get the axe. If you're a third-party developer totally invested in Swift, this thought ought to frighten you at least a little. And ask yourself, if the pendulum swings that way today, how much would have to change and how long will it take for the pendulum to swing the other way? At what time, in what year, would it be more painful for Apple to axe Swift than Objective-C?
You may be muttering to yourself that Apple couldn't possibly betray developers that badly by ditching Swift. How could Apple executives sleep at night? I suspect, on mattresses full of cash. They wouldn't give it a second thought. They might even praise themselves as courageous. You only have to review the history of Apple developer relations to see the long string of deprecations, disappointments, suffering, and broken promises. Objective-C garbage collection, 64-bit Carbon, the Cocoa-Java bridge, Yellow Box for Windows, Dylan. Need I go on? I could go on. Apple evangelists will tell you that Swift is the best programming language ever and then turn around and tell you that we've always been at war with Swift.
When Apple decided to create Swift, what was their original plan? I see three possibilities:
- They really did intend to support both Objective-C and Swift indefinitely.
- They intended to eventually deprecate Objective-C and move exclusively to Swift, as the developer consensus believes.
- They didn't have a solid plan and weren't sure whether Swift would even catch on.
The first is a dumb plan, for reasons I've already outlined, so I'll give Apple the benefit of the doubt and say it wasn't 1.
If 2 was the plan, I really wish Apple had been more forthcoming about it. The message from Lattner would have been misleading at best. If Swift is the future, why not be absolutely clear with developers about that, and let us plan accordingly. The uncertainty is the worst aspect of this. We can accept that Swift is the future if we have no choice. But if Swift is Apple's choice, and they still give us the illusion that we have a choice, then some of us are unknowingly making the wrong choice, which is harmful for everybody.
My opinion is that 3 is true. I know a lot of people think Apple is operating according to some grand, secret, master long-term plan. Does Apple have long-term plans? Undoubtedly. Are the plans more than tentative? I doubt it. In the tech industry, you can make long-term plans, but you can't expect to keep your long-term plans. Technology changes … swiftly. You have to stay "agile" (but not "Agile"). You have to be able to react to what your competitors do. Consider Lattner's departure: was that part of Apple's plan? Plans change. They must change. Third-party developers pounced on Swift immediately, but Apple also had to consider the possibility that Swift would produce a collective shrug in the development community. Hope for the best, but plan for the worst.
By all accounts, the Swift project was a secret even within Apple. It was known by only a select few people. When Apple announced Swift, it was as much a surprise to most Apple engineers as it was to third-party developers. Apple engineers and engineering managers were not prepared for it. And this presents the biggest challenge to the Swift programming language: the internal conflicts between Apple engineering teams. The Swift team, with executive support, presents Swift as the future of Apple app development. But the Swift team can't just sweep away the present and make the future an established fact. The present within Apple is Objective-C. A lot of Objective-C. Decades of Objective-C that accumulated from even before Apple acquired NeXT. The Objective-C code base is not simply going to disappear on its own by wishful thinking. You present Swift to a bunch of teams within Apple that are very time constrained and resource constrained, and they're going to tell you to go jump in a lake. They may like the idea of Swift, but WWDC is coming soon, and work needs to get done. Maybe next year. Or the year after that.
How can Apple reconcile these competing interests? They want Swift to be the future, but they also have a ton of Objective-C code, and they want to continue their agile software development, all while employing only the best engineers. And maintain software quality. (One would assume they care about quality, hopefully.) Something eventually has to give. Meanwhile, outside developers will place more demands on Apple for Swift resources. The API references are probably automated to a significant extent, so a dual stack there wouldn't be a huge problem, but Swift developers are going to want Swift documentation guides and Swift sample code. If the official position is that Apple supports both Swift and Objective-C, do they write dual stacks for all documentation, all code samples? And how much effort do they put into updating very old Objective-C oriented documentation?
What is the consensus response to this problem? The people who think Apple will deprecate Objective-C, how do they think Apple can handle it? Some people suggest that Apple will deprecate Objective-C externally, but they will continue Objective-C development internally and indefinitely. However, I think these people underestimate the problem. Given the amount of Objective-C code Apple has, and the constraints they're working under, taking the slow road internally to a Swift future would be a very slow road indeed. How long do you think Apple would have to maintain an internal Objective-C toolchain? If you're not thinking 5 years, 10 years, even more than 10 years, I don't think you appreciate the size of the problem. To me it seems extremely unlikely that Apple would put the resources into developing and maintaining an internal-only version of Xcode, internal-only Objective-C APIs, internal-only Objective-C documentation (everyone needs documentation), etc. And once again, if Apple were to officially deprecate Objective-C, the number of Objective-C developers would drop even more precipitously than now, so where in the world is Apple going to find people to maintain its Objective-C code base indefinitely into the future?
Let me refute a possible objection to my arguments here. The objection is that Apple has had a dual software stack all along: Objective-C and C. Foundation and Core Foundation. So adding one more language to the stack is nothing new. This objection is superficially convincing, but it has an inherent flaw. It's true that C and Objective-C are separate languages, but the analogy with Swift breaks down because C is a subset of Objective-C. If you learn Objective-C — learn it well, anyway — then you've learned C too. It doesn't matter that many people learn C first and Objective-C later. Indeed, that's the way I learned them, and the educational route I would suggest. But learning C and then Objective-C is not the same as learning two programming languages. In effect, it's simply learning Objective-C in two phases. Everything you learn about C is directly applicable in Objective-C. It just works, so to speak. That's not true at all of Swift. There is some overlap, of course, because Swift was designed with Objective-C in mind, but in no sense is one simply a subset of the other. Swift and Objective-C are incompatible in a way much worse than, say, C++ and C, which are pretty close but not quite compatible.
Moreover, C alone is not truly a first class language for developing iOS and macOS apps. Can you make an app that's entirely C? Perhaps, but certainly not easily. The application development environment for C was not Cocoa but rather Carbon, and Carbon has been largely deprecated. There are quite a few supported C API for Apple platforms, but C is not in the same class for app development as Objective-C or Swift.
Revenge of the Something Something
This is only my suspicion, but I suspect that Apple didn't anticipate Swift becoming so popular so soon. The whole strategy makes a lot more sense if Swift experienced a slow growth over a period of many years. The dual software stack is economical if your developer base is divided roughly evenly. Both Apple and third parties would have plenty of time to migrate their existing code bases from Objective-C to Swift. Swift could still be the future, the sole first class language eventually, but that would be just the distant future. It may have been a failure of planning or imagination to see that Swift could suddenly overwhelm Objective-C in developer mindshare. And now Apple faces some difficult choices. How do they deal with the unexpected popularity of Swift outside of Apple when the inside of Apple is simply not ready for it yet?
I doubt that Apple will backtrack on Swift. Although I think the departure of Lattner makes that possibility a little more probable than before. Many developers have bet their livelihood on Swift. It may have seemed like a good bet at the time, and maybe it'll pay off. Probably it'll pay off. What if it doesn't, though? What if the longshot wins? What if there's a change in management, or simply of change of mind within management? What if Apple decides that their own internal constraints are more difficult to overcome than they anticipated, and it's not profitable to switch languages? Can you rule out that possibility? I'm afraid that most people aren't prepared for that world of hurt. If it happens, there's going to be a lot of screaming and crying. Except among Objective-C developers, who will laugh and party like it's 1999. Or at least 2001.
On that note, Happy Valentine's Day!