Swift One Year On

With WWDC 2015 just a few weeks away, now seemed to be the perfect time to reflect on a year with Swift. When Apple’s Craig Federighi (SVP of Software Engineering) announced Swift there was an almost euphoric response from many parts of the Apple developer community. 

The sheer level of technical ambition was breath-taking. Apple had built a brand-new language that could be fully integrated with existing code, all of the Cocoa APIs, was easy to learn, encouraged crash resistant code and even delivered a performance boost. John Siracusa was lifted above the Ewokian throng and carried out of Moscone West on a throne. You get the idea. 

However, our response was ultimately tempered by the initial quality of the tools. This reality should not have surprised anyone. Apple had kept the language a secret even internally, and with little (not quite no) dog-fooding . Eager developers downloaded the first betas of XCode 6 and got started; many could see promise, the experience was painful. Playgounds (designed to make learning and experimenting in the language easy) were actually unstable and frustrating. Some of the language fundamentals were poor; copy semantics for arrays were confusing at best, and whilst the language came baked with arrays and dictionaries sets were nowhere to be seen. All of these problems paled into insignificance when compared to a truly explosive XCode. Not only did core parts of the build chain crash frequently with painful build times for even medium size projects  when they did work, but the interactive experience was just horrific

 Where 'temporarily limited' means "get used to this, you'll be seeing it a lot for the next 8 months. 

Where 'temporarily limited' means "get used to this, you'll be seeing it a lot for the next 8 months. 

Iterate

With each new beta, the situation improved, some of the highlights included

Despite these developments, it was clear that by the time Apple threw the switch on iOS 8 and released it along with the first Swift apps to the world, that Swift was still a long way from finished. It would have been reasonable to assume that we would hear little else from Lattner and his team until WWDC 2015. Reasonable, but wrong. Swift has continue to develop with language updates (we are now at 1.2) as well performance and bug fixing. 

Swift 1.2 in particular seemed to signal more clearly than any of the other updates that Apple was serious about Swift, and serious about its claim that whilst binary compatibility would be maintained, the language itself was not done. 

What defines Swift?

Few areas of Swift are as distinctive (and sometimes as divisive) as optionals. Optionals force the developer to consider if it is possible for a pointer (a reference to an area of memory that stores an object in a program) to be nil. That is, point to nothing. C or C++ code would crash if you tried to use one of these nil pointers to call a method on that object (do something with it). In Swift you must declare that something can be nil by appending a ? to its type. When you use it, you must acknowledge the result of any method you call could be nil (?) too. Or force it to assume it’s not nil with the ! character. What this does it make it hard for the developer to hide from the fact that their code can’t assume a pointer points to a valid value. The initial release of Swift provided mechanisms for helping the developer work with these optionals. 

Some of the biggest changes in Swift 1.2 increased a developer’s ability to minimise the number of lines required to check to see if optionals had a valid value. 

Swift 1.0 [1]

//Check all my pointers are valid and a property is over 100
if let myObject = myObject
    if myOtherObject = myOtherObject
        if myObject.property > 100 {
            //Do something cool
        }
    }
}

Swift 1.2

//Check all my pointers are valid and a property is over 100
if let myObject = myObject, myOtherObject = myOtherObject where myObject.property > 100 {
    //Do something cool
}

It’s hard for a seasoned developer like myself to know if these things make it harder (?! Everywhere and lots of checking might increase the complexity to a beginners mind) OR they actually reduce the number of time a beginners program inexplicably [to them] crashes. What is clear is that in a rather intensive period of development with Swift 1.2 I was able to focus purely on the algorithms I was developing, and let Swift focus on potentially explosive nils. Every time you consider adding a ! to force the optional to be treated as a valid pointer… you feel dirty. You don’t do it. Your code doesn’t crash. Despite having a large number of beta-testers, we’ve only had functional defects, no crashes. None. I’m not an expert on all current languages, but for me optionals set Swift apart from every other language I have used, and certainly from other languages that are good candidates for developing on Apple platforms. They are unique and valuable.  

In Summary

Where are we now? The development process for Swift is now stable. Although the language has evolved and improved XCode has enabled early adopters of Swift to keep up with the changes as they happened. I’m not convinced Swift is an easy first language to learn. Were someone with another language under their belt to start now they would find themselves working with a mature language supported both online and in-print. For anyone wishing to start development for Apple platforms, they should start with Swift. For those of us with over a decade invested in Objective-C & Cocoa the decision is more personal. I believe Swift is ready for us, but exactly when you chose to jump is something that Apple has, for the time-being at least, left to each individual developer. 

However, I know that every time Swift reminds me that the variable is optional, I’ve just avoided a bug and saved time. Maybe just a minute, but maybe a few hours, and for any independent developer time is money. 

 

Footnotes

1. This could have been done more briefly of course, but I believe that the Swift 1.2 approach is as concise but more explicit. 

if myOtherObject!= nil && myObject != nil && myObject!.property > 100 {
    //Do something cool
}