Hello Swift & optionals

Taking a look at Swift with a bit more details on optionals.

Introduction

There has been a lot of blog posts about Swift, the new programming language introduced by Apple on this year WWDC. It’s exciting new language for Apple platforms and it’s definitely the future. But as a newcomer to long standing single-player in the field - Objective-C - it’s natural for developers to compare it to its older brother. In this article I’ll take a quick look into Swift optionals and how I grew to use them. The article is geared towards developer knowledgable in Objective-C interested in Swift, but perhaps uneasy with its strong type and optionals.

Quick comparison

One of the most distinguishing properties of Objective-C is its dynamic type. It’s “anything can be anything” dogma allows great freedom to responsible developer, but can cause all sorts of nasty bugs if not careful. It also keeps code simple - there’s no need for explicit if (object != nil); as long as we take care of what kind of values are returned from methods, we can get away with simply sending the message to nil. Coming from statically typed languages and platforms (C, C++ and C#), I grown to like and appreciate this dynamic nature, so was a bit skeptical on coming back to static world with Swift. But there are couple of things which I really longed for that drew me to give it a fair try - absence of header files and #imports for example.

Swift quick spin & optionals

After couple of command line tools, and letting it stabilize, I decided to try Swift on Mac application - together with newly introduced storyboards in Yosemite. While I loved the new syntax, I also found it awkward in places. Some things that would be simple one liner in Objective-C resulted in multiple lines of code in Swift. Most of these were of course due to strong type nature of Swift, but some - explicit optionals in particular - simply felt like additional burden to my Objective-C conditioned mind. Sure, they sound great as a feature, but they felt awkward in practice, especially on a platform that has long tradition of treating nil in a very special way.

Optionals and nil in Swift require the same processing as in most other languages/platforms (C++, Java). That is, developer is responsible to explicitly verify that the value is not nil before using the object. However in addition to that, Swift requires additional syntax to get the value out of the optional - called unwrapping the optional. There are several methods of doing this. The cleanest is if let statement, but using it breaks my habit of maintaing “happy path” in my methods - the code should fail early on errors which keeps error detection and handling code close together and “happy” code aligned to left side:

- (void)method {
    if (error) {
        // handle error
        return
    }
    
    // continue with "happy" path
}

Without if let, we’re left with explicitly unwrapping optionals. No big deal, but this ends up with tons of question marks or exclamation points littered in the code making it harder to read. It was really irritating, especially when changing property type from optional to non-optional or vice versa; a simple one char change would cause many many syntax errors throughout the class or application. No big deal, right - just use non-optional all the time. Except that you simply can’t do that because of the way Swift requires property values to be set: all values need to be assigned by the time a class is initialized. With Cocoa or UIKit application, that simply cannot be done in all cases; sometimes a value is only available after the view has been loaded from nib or storyboard. Think of passing values from parent to child controller, or getting default value from an outlet.

Implicitly unwrapped optionals to the rescue

This was driving me crazy until I learned about implicitly unwrapped optionals. These are basically optionals, but you can treat them in code as if they are plain values. The developer is still required to make sure the value is not nil - trying to access the value from nil will cause runtime exception. But it doesn’t require using question or exclamation marks all over the place. Basically you’re telling the compiler: don’t worry, I know the value will be there by the time it’ll be accessed. This brings Swift on par with patterns you’re probably used to if you used programming languages other than Objective-C - Java or C++ for example.

Here’s an example of using implicitly unwrapped optional:

class MyClass {
    func doSomething() {
        if self.value == nil {
            return
        }
        self.value *= 2
    }
    
    lazy var value: Int! = 0
}

As you can see, you declare implicitly unwrapped optional by adding exclamation mark at the end. From then on, you can use the value as if it was non-optional. But as said, you’re still responsible for making sure it’s not nil.

Conclusion

The whole explicit optionals handling in Swift is there for safety - compiler will not allow you to use a class that has not been properly initialized and will make sure you’re not accessing optional value without testing for nil. The idea is good, but implementation requires the developer to deal with little code nuances instead of concentrating on what really matters - creating apps. With implicitly unwrapped optionals, my life in Swift has become bearable. Coming from Objective-C though, dealing with optionals still feels like doing a step backwards. And it’s a shame - there’s so much to love about Swift, but it feels like lost opportunity too - it’s not often such a great change is introduced to a platform, but instead of concentrating on higher level constructs, it requires developer to deal with pesky little details. In some areas it feels like a language written by compiler enthusiasts for their fellow think-alikes. However, from seasoned app developer point of view, most of these details feel like an obstacle more than help.

But don’t get me wrong - in general I prefer Swift to Objective-C, it’s clearly the future and I’ll definitely use it for all my future projects. Even though it’s been developed secretly for quite a few years, it’s still a newborn. We’ve seens many changes, even breaking ones, with every Xcode 6 beta since its announcement in june 2014. It’s actively developed by a talented engineering team in Apple and I’m sure it will receive even more treatment now, when it’s officially reached 1.0. And even more so in time, when developers and especially Apple itself embrace it on real world apps.

Stay tuned!



Want to reach us? Fill in the contact form, or poke us on Twitter.