If you follow me on Twitter, I’ve made a lot of noise about how I don’t think developers should be adopting Swift in it’s current state. My problem isn’t with the idea of Swift, or replacing Obj-C. I believe Swift could, in the coming weeks or months become a language suitable for writing production code. But I don’t believe it is such a language today.
When I look at Swift, I see a language with a few issues, even compared to it’s non bracketed brethren:
No Access Modifiers
Swift has currently has no way of declaring a property as public, private, or protected. Why is this important? Many classes have functions that are not meant to be called outside of certain processes, or may be called internally for one time setup. An example is some sort of function that may be shared by multiple paths for initialization. A view controller might have a shared initialization function shared between awakeFromNib and initWithCoder, as one example. This function is not intended to be called or known by outside implementers of such a class. Typically, as a developer, you make these functions private, which hides them from public view. This means someone is not going to trip up and call your function when they shouldn’t, whether it is someone on your team, someone in the public using your class as part of a framework, or you three months from now. In my opinion, the lack of access modifiers makes it impossible to write a well formed Cocoa class in Swift.
In Obj-C it was possible to dump or inspect a class, figure out the internals of a class, and still call a private function. But the point in declaring something private is not to enforce privacy, but to tell others using your code that something should not be touched by them. If I get an email from someone telling me that my class broke after they touched a private method, I get to write them a strongly worded email telling them they should have known it would break because it was a private method. I’ll get to break up my day a bit, and use the caps lock key, which I don’t get to use often when writing email.
It’s worth noting that C++. Java, C#, and Obj-C all implement private/protected/public in way way or another. Apple has already said access modifiers will be coming to Swift at a later date. But it’s the present implementation of Swift that worries me.
There have been more than a few posts that are finding Swift’s performance is substantially lower than C or Obj-C. Modern processors may be fast enough to absorb the performance hit, but I don’t like this trade off. On mobile devices, performance is directly linked to battery life. Use less CPU, and you’ll use less battery on a mobile device.
You can modify the compile settings to increase the Swift optimization level that gets similar performance to Obj-C, but by doing so you lose a lot of the safety of the Swift language, which is one of the major reasons to adopt the Swift language to begin with.
It’s my belief that the trading a responsive user experience and low power usage is not worth the tradeoff for the syntactical cleverness the Swift language provides, for the time being.
So Why Not Start Writing Swift Now?
I don’t think Swift should be deployed into any real projects at this point. Am I playing in Swift? I sure am. The Playground feature is extremely useful. I can test my understanding of the Swift language, and practice writing Swift code, on up to writing entire sets of Swift classes. It’s great for filing radars, and I really want Swift to be a great language.
I think not having access modifiers alone is enough to consider Swift not deployable in it’s present form, however fancy Swift is. There are strong opinions out there that writing all new code in Swift today is the only way to really learn Swift. Some have compared the situation to Cocoa vs. Carbon in the early OS X days, where Carbon developers fell behind when because didn’t learn Cocoa. I don’t buy that.
It’s important to remember the Swift’s primary (and really only) API is Cocoa. Not just Cocoa: the Obj-C version of Cocoa. Do you know KVO under Obj-C? Great! You know KVO under Swift as well. Notifications, delegates, model view controller, user interfaces, frameworks… All these concepts carry over identically into Swift. Swift and Obj-C are just two different grammars for accessing (literally) the exact same vocabulary of Cocoa. If you know Cocoa, you’ll feel right at home in Swift inside of a week. An Obj-C developer is not missing out on much right now. And if Apple backtracks or alters certain parts of Swift, hands on knowledge gained now could be outdated in a matter of weeks or months. Swift has some clever tricks to make code shorter or cleaner, but these sort of language features aren’t necessary to write good code.
I think Swift could be something great. But Swift is a tool, just like any other tool. And as a developer, you don’t evaluate a tool on how new it is, but how well it functions. Swift has several issues that impair it’s function. It’s an elegant language, but it simply doesn’t deliver today what developers need to write good code.
Big Nerd Ranch wrote a blog post advising developers that they should continue writing code in Obj-C for now. They said some of the things I’m repeating here, but I think they were also wise in suggesting sticking learning Cocoa through Obj-C for a different reason: Without things like access modifiers, it’s not actually possible to teach developers to write good Cocoa code in Swift. It would be hard to write a blog post or run a class to teach students how to program, and not touch on the concept of public vs. private. It would almost be irresponsible.
Another important point is that Apple has said they’re going to fix a lot of these issues, and I think they well. But no one knows when (although I’m betting access modifiers will come pretty quickly.) I don’t want to bet that Swift’s problems are going to be fixed for an app I’m targeting for iOS 8. Worst case, Swift’s performance could (worst case) even take a year or two to completely bring up to speed. Do you want to risk your project’s user experience against fixes that don’t have a time line?
To date, not single fully Swift application has shipped. I have not seen a major application in Swift. Anyone saying Swift is usable for a large code base can’t actually know that because no one has written such an app, and a demo Flappy Bird application does not a major application make. As I’ve pointed out, there are measurable and observable issues in creating a large application or maintaining a complicated code base in Swift. And without private methods, it’s pretty much flat out impossible to ship a Swift framework or library that’s usable.
Swift is going to get where it needs to be, and it will be a great language when it does. But as a developer, it’s important to remember that the most important thing for your project is the user experience. We need to be honest with ourselves about the strengths of our tools, and not just start using something only because it is new. A user will not be impressed by your application because you adopted Swift early. They’ll be impressed if your app works fast, doesn’t drain their battery, and it works reliably. And I don’t feel Swift provides the performance, or the tools developers need to write great applications. It will, someday, maybe someday soon. But for now, I’d rather give my users the best performance and quality I can.
Addendum – A nit pick on “Swift does not have pointers”
I’ve seen many languages claim to not have pointers. To date, I have not seen a single language that does not actually have pointers. It is impossible to not have pointers in a programing language on a computer that works by having banks of memory with addresses.
Even when you’re working with Swift types natively, pointers are still there, they’ve just been hidden. You point to array entries with offsets, much in the same way you point to C buffers with offsets. If I try to fetch from an array with an offset beyond the range of the array, my Swift application will throw an exception, same as in a lot of cases if I had a bad pointer.
Wrapping and unwrapping is also, essentially, pointers. A wrapped object is a pointer to either nothing or the real object. Unwrapping is essentially a dereference. And again, the behavior is the same. If you try to dereference a bad pointer, you will crash.
Swift does make a few advancements. Strong typing helps to ensure that you can’t mismatch pointer types. But C pointers definitely still exist, and Obj-C had a lot of it’s pointer problems cleaned up previously with weak references. It does make a big effort to try to avoid garbage pointers, but it doesn’t fix this behavior for C which is where you are most likely to have garbage pointers. Obj-C solved the garbage pointer problem with weak references a few years ago, so the lack of unmanaged pointers doesn’t get a developer much of an advantage over Obj-C.
Why did I bring this up? A few developers have claimed that Swift’s problems are outweighed by no longer having to deal with pointers. I don’t think anyone should be promising that Swift gets rid of pointers. I think a more realistic claim is that Swift makes some types of pointers safer, but that pointers in many forms are still present.