It's summertime and I've been spending some time learning Swift, Apple's new computer language. It seemed gimmicky when it was announced -- the name, the so-called “playgrounds,” the stripped down syntax. Boy was I wrong. It's a major new language that's as sophisticated as C++ or Java. And, given that it's been designed from the ground up (albeit with some fealty paid to compatibility with ObjC and Apple environments like Cocoa), it feels very fresh and new. Imagine the low level control of C++ with the syntactic elegance of Python or Ruby.
My first language was BASIC, and I have a special affection for Perl, but the language I've spent the most time with is Java. "Special affection" is not a phrase that comes to mind. Beyond the usual frustrations that people have with Java, I'm often stymied by how the Java virtual machine quarantines you. Let's face it, the fun stuff happens at the level of native code. The two largest projects I've worked on over the years, Carnivore and Kriegspiel -- which sadly are now effectively offline (more on that soon!) -- both require a certain amount of “closeness” to the native OS level. Carnivore needs to access the network adapters, something prohibited by Java (without using a native bridge), and while games like Kriegspiel don't need native code per se it's much easier to program things like AI and graphics in a language that compiles to native instructions. Yes, there are ways to bridge Java into native libraries. And both Carnivore and Kriegspiel were successfully written in Java. But I ask you, have you ever coded a JNI bridge? Me neither. And I don't ever want to. In other words I've been looking for a reason to ditch Java. And this might be the right opportunity.
Sure, Swift is limited to the Apple environment. But it's no secret that Microsoft is a disaster; I can barely get myself to power up my Win machine when I need to test something. Frankly I'm sick of trying to release and support software on multiple operating systems. It's a major headache. (I'll always have a fondness for Linux though, even if the easy accessibility of the command line in OS X has effectively neutered my desire to switch to Linux for day to day purposes.) Also, given that it will be made open source, it's inevitable that Swift will migrate to other environments in the future. Regardless, my days of supporting software on Windows devices are probably over. It's time to focus on iOS and OS X. And if I want to explore Android in the future, well I still have my original Java codebase intact.
As for more substantive thoughts on Swift, I still have to spend time with the language. But a few initial things come to mind. First, a very general and perhaps naive observation... I'm struck by how similar computer languages are to each other. Yes, yes, I know computer nerds like to trot out Lisp or Haskell (not to mention Brainfuck) as illustrations of alternatives to mainstream procedural or object-oriented languages. But the fact is most modern languages are largely the same: they all observe a set of technical and philosophical assumptions about algorithms and data structures; they all use logical and mathematical operators; they all have ways to abstract data and/or operations into aggregate units (be they tuples, records, structs, or objects).
In fact it's a bit of a relief that languages are largely the same, because if you master one of them you essentially know pieces of all of them. I reiterated this to my students last semester who were learning Processing as their first language: all of the basic concepts they were learning were easily portable to other languages and environments. There's an old saying in computer science about semantics and syntax, that if you understand semantics it's trivial to learn a new syntax. For instance, if you understand the concept of a `while` loop, it's trivial to translate the syntax from one language to another. It's almost like there's one language -- pseudocode -- and everything else is just syntax.
It seems like the only real change in languages over the last 20 years is the gradual elimination of pointers and the automation of memory management. Swift is similar to Java in that regard, and thus a dramatic improvement over Apple's previous language of choice, Objective-C, which is, let's be honest, an absolutely hideous language. I'm sure I speak for many when I say that I'm glad I don't have to manually allocate and deallocate memory any more when I create and destroy objects.
The second observation is more idiosyncratic: after years of trying to make it work I'm finally waking up to the fact that Java is just not a great environment. Or at least it's not the best environment for me. There's the whole lie about "write once, run anywhere," which I won't dwell on. What I mean instead is that the whole philosophy of "everything is an object" just doesn't make sense. Some things work well as objects. But not everything. With Java I found myself constantly using the singleton pattern and stubbornly relying on static methods. Yes I'm one of those people! In other words I found myself constantly trying to write Java code in a way that would circumvent Java's main reason for existing. Obviously not an ideal situation. By contrast, Swift is much more level headed about the object-oriented paradigm. Sure, you can define objects if you want, but there are other data structures available as well. (In Swift the main difference between structs and objects are that structs are pass-by-value and objects are pass-by-reference. It's a simple distinction with profound repercussions.) Swift is thus much more forgiving when it comes to global variables and function declarations -- not to mention having a much saner way of dealing with name spaces without all of Java's package/classpath bullsh*t.
There are a lot of other small things I could talk about too.. the IDEs for example: I never thought I'd be defending that old lumbering Eclipse, but I almost miss it now that I've switched over to Xcode. Sure, There's some great things about authoring Swift in Apple's IDE: despite still being pretty buggy, playgrounds are very cool ways to hone short code snippets that you can paste back into larger projects; I'm also super glad not to have the Ant/Maven/etc headache when it comes to building; and I find I use the debugger more and have even written a few unit tests (yay!), two things that I found annoying in Eclipse and thus avoided.
But in other ways, Xcode still has a long way to go. The interface builder is a disaster -- in fact it's been a disaster for years. (It's surprising Apple still hasn't solved this.) And since Swift is still so new, there are some very basic things you can't do yet in Xcode. Like refactoring. Yes that's right: you can't refactor Swift code! Pretty ridiculous. Also, Xcode doesn't handle certain conveniences very well, conveniences like autocomplete. It does have a limited autocomplete functionality, but I find that Eclipse is much better at recognizing static issues in your code and then suggesting the correct solutions. (For example if you have a Java object that implements an interface, Eclipse will automagically insert all the boilerplate code into the object that you need to satisfy the interface. As far as I can tell Xcode doesn't do this for you; it just throws an error saying you haven't satisfied the interface, or what in Swift are called "protocols.")
But these are all details. Overall Swift is amazing. They basically stole every good innovation found in other languages and put them into a single elegant language. Plus a few fun things like full Unicode support (translation: you can write code in emoji!). And at the same time they seem to be pushing the language in some interesting new directions -- such as protocol-oriented programming. As I said I'm still getting the hang of it. But I'll try to post more in future weeks...