A fast look at Swift, Apple’s new programming language

For better or worse, Apple's new language lets you do things your way.

Closures, generics, and operator overloading

Apple introduced blocks, small chunks of code that can be passed around within an application, several OS iterations ago. They're great for things like dialogs, which typically have to execute some code when the user dismisses them. You can keep the code for the block where the dialog was handled (where it logically belongs), but hand it to the dialog, which only executes it once a button is pressed. It's both a convenience and a way to improve the readability of code. So, not surprisingly, blocks are back in Swift, this time under the guise of their formal name, closures.

Apple's Swift guide is free in iBooks.

Apple

It's possible to hand blocks of code around in C as well. Functions end up with an address in memory, and you can make a pointer to that function. Swift offers something similar, allowing you to set variables that can hold any function that matches a specific signature. It's a pretty logical extension from closures, and again abstracts away the risks of working with an actual memory address.

As we mentioned above, Swift adds generics, functions that can work with a variety of variable types. You can create a generic function that sums the contents of an array, for instance, regardless of what kinds of numbers are stored in the array. You can also restrict the types of objects that a generic works on by setting them to limit their inputs to specific protocols. For example, all of Swift's basic variable types implement the Equatable protocol, which allows them to respond to the == operator.

Obviously, it could be useful for any custom classes to also implement Equatable, which means that they have to be able to respond to == as well. To do this, Swift uses a feature called operator overloading, which allows a programmer to define how to implement basic operators for custom classes. So, if you implemented a custom class to represent hard drives, you can overload == to check whether the manufacturer, size, spindle speed, and so on were all identical. You could also overload + to simply provide a new drive with the combined capacity of the two.

What's missing?

I'm sure <your language of choice> contains dozens of features that Swift doesn't, ensuring that Apple's latest effort will be crippled from the start. But the thing that leaps out is a complete lack of error catching. Yes, the compiler is now incredibly smart about spotting common errors, and the language features several intelligent ways to avoid doing dumb things with nil objects.

But no matter how clever the language and compiler are, people (like, say, me) are going to find ways to screw up. And we like to screw up gracefully, rather than see the program come crashing to a halt.

Of course, the current release is a beta, and Apple is almost certain to have designed the core language with extensibility in mind—it's unlikely to have forgotten its experience with adding features to Objective-C. There's still the chance that error catching could appear as early as the public beta if the developer response demands it (and the same goes for other features that you feel Swift is missing). Hopefully, Apple won't try to convince everyone that nobody really needs it until it's introduced as the greatest thing since sliced bread in OS X Weed.

Is it any good?

Swift isn't a radical departure in many ways. Apple likes certain design patterns, and it constructed Objective-C and Cocoa to encourage them. Swift does the same thing, going further toward formalizing some of the patterns that have been adopted in a somewhat haphazard way (like properties). Most of the features Swift adds already exist in other programming languages, and these will be familiar to many developers. The features that have been added are generally good ones, while the things that have been taken away (like pointer math) were generally best avoided anyway.

In that sense, Swift is a nice, largely incremental change from Objective-C. All the significant changes are in the basic syntax. Use semicolons and parentheses—or don't, it doesn't matter. Include the method signature in the function call—but only if you feel like it. In these and many other cases, Swift lets you choose a syntax and style you're comfortable with, in many cases allowing you to minimize typing if you choose to.

Most of the new features have been used in other languages, the syntax changes get rid of a lot of Objective-C's distinctiveness, and you're often able to write equivalent code using very different syntax. All of this enables Swift to look familiar to a lot of people who are familiar with other languages. That sort of rapport has become more important as Apple attracts developers who'd never even touched C before. These people will still have to learn to work with the design patterns of Apple's frameworks, but at least they won't be facing a language that's intimidatingly foreign at the same time.

In general, these things seem like positives. If Apple chose a single style, then chances were good that a number of its choices wouldn't be ones we'd favor. But with the flexibility, we'll still be able to work close to the way we'd want.

Close, but not exactly. There are a couple of specific syntax features I'm personally not a fan of and a number of cases where a single character can make a radical difference to the meaning of a line of code. Combined, the syntax changes could make managing large projects and multiple developers harder than it has been with Objective-C.

What's Apple up to?

For starters, it's doing the obvious. Swift makes a lot of common errors harder and a number of bad practices impossible. If you choose, you can write code in Swift pretty tersely, which should make things easier for developers. It adds some nice new features that should make said developers more productive. All of those are good things.

More generally, though, Apple is probably mildly annoyed with people like me. I spent time getting good at using autorelease pools, my apps didn't leak memory, and I didn't see the point in learning the vagaries of the syntax required to make sure Automatic Reference Counting didn't end up with circular references that couldn't be reclaimed. I wasn't a huge fan of the dot notation for accessing properties, so I only used it when it couldn't be avoided. In short, I was a dinosaur in waiting.

People like me are why the runtime and compiler teams can't have nice things. If everybody's using the same features, it's easier to get rid of legacy support and optimize the hell out of everything that's left. A smaller memory footprint and better performance mean lower component costs and better battery life, which are very good things for the company.

Apple promised better performance with Swift, and you can see some places where it might extract a bit. Constants are a big part of Swift, which makes sense. If you make a stock-tracking app, the price may change every second, but the stock's name and symbol change so rarely that it's just as easy to make a whole new object when this happens. Declare the name and symbol constants, and you can skip all the code required to change them in a thread-safe manner. Presumably, the compiler can manage some optimizations around the use of constants as well.

Unlike the dinosaurs, we can see Chicxulub coming. Two or three years from now, when Apple announces that the future is Swift and it's ready to drop Objective-C, we won't be at all surprised. And I won't be at all upset, because I'll have spent the intervening few years making sure I know how to use the new language.