Optionals! What is it good for...

Before we start diving in and look how to use optionals, I think it will be a good start to make clear what problem they solve. I'm sure a lot of people will get mad about the new daily ?-, !-, if let-business just because they don't realize how worse it was in the old Objective-C days.

The old way

Everytime we write a function, declare a property, variable or constant we promise other parts of our code, that it can retrieve a value under this name. But like in the real world we are not always capable of keeping our promises. In the Objective-C days when we promised to return an object-pointer, but weren't able to provide a meaningful value, we returned nil instead. Which was basically a void* pointing to special memory represting a nonexistent object.

nil was kinda great, because it had the special property that every method call to it would fail silently without any exceptions being thrown. I've always saw elegance in it and used nil a lot. But there are problems though. First there is no way to tell if a function is returning nil just by looking at the signature. You always had to consult the documentation for this. And telling if a variable could contain nil without investigating it's source was simply impossible.

Which brings up the second issue. Suprising bugs! Imagine a long chain of method calls and one of the methods is unexpectedly returning nil. The whole method chain will happily proceed further without a sign of failure and in the end you sit there and ask yourself why your beautiful crafted code has absolutely no effect.

And what about primitve types like Int. There is a method in NSArray for example called - (NSUInteger)indexOfObject:(id)anObject. Obviously there is a need to return nothing. Because there can be the case that a given object isn't contained in the array. For problems like that the Apple guys invented NSNotFound, which is simply an alias for NSIntegerMax. Arrrrghhhh! Don't need to say how bad this is. It always felt like a dirty hack in an otherwise admirable framework.

Let's throw Optionals on the Problem

You can think of an optional type like a two cased enum with an asocciated value being the actual value we want to make accessible:

enum Optional<T> {  
    case Some(T)
    case Nothing
}

You see an optional is like a box where you put the actual value in. But because the box itself gives the value extra context, it's possible to distinguish an actual value (Some) and a nonexisting value (Nothing). We can wrap any value, not just objects, in an optional, determine if there is a value and unwrap it again. Problem solved. Optionals are actually not a new idea to solve the problem of nothingness. They are everywhere in the functional world, you will come across them in Haskell as Maybe or in Scala as Option.

How to use them

Declaring an Optional

You declare an optional type by first saying what should be in the box and subfixing it with a ? to indicate the possibility that there might be no value.

let bestNicCagePerformance : String?  

But keep in mind bestNicCagePerformance isn't a String it's an Optional<String> which needs to be unwrapped before using the actual value. Also note that an optional is initialized with nil by default, so it's not an error to not initialize them explicitly in your classes and structs.

Wrapping and Unwrapping

Wrapping is quite easy. Swift will make it automatically every time you assign to an optional or return something that is declared optional. In this context nil gets a new meaning in Swift. It is no longer a void* it is the now the way of saying Optional.Nothing.

func calculateAnswer(cond: Bool) -> Int? {  
    if !cond {
        return nil
    }

    return 42
}

func(false) // Nothing  
func(true) // Some(42)  

See how we just return our value or nil. But because we declared our return type as Int? Swift will wrap the value in an optional for us.

For unwrapping there are a few options. There is forced unwrapping. When you place an ! after the optional's name you force it to return you its value. But be careful. If the optional is nil, forced unwrapping will result in an exception being thrown and an eventual crash of your application.

var jedi : String? = "Luke Skywalker"  
print(jedi!) // Will print "Luke Skywalker"

jedi = nil  
print(jedi!) // Will throw exception!!!  

It's obviously recommended to first check if the optional holds a value or not. Luckily nil is defined as being equal to Optional.Nothing. Therefore we can transform our code to a safe version like this:

var jedi : String? = "Luke Skywalker"  
if jedi != nil {  
    print(jedi!) // Here it's safe to force unwrap 
}

Because this is such a common pattern, there is another form of unwrapping called optional binding.

var whoShotFirst : String? = "Han"  
if let perpetrator = whoShotFirst {  
    println("\(perpetrator) shot first.")
} else {
    println("The answer will be forever unknown.")
}

With optional binding we do two things. Check if a value exist, then bind the actual value to a local name. When this succeeds the if-block gets executed, otherwise an optional else-block is executed.

This gets even better in the recently released version 1.2 of Swift. 1.2 got if-let-bindings on steroids. It allows to do multiple bindings in one if seperated by commas. They get executed in the specified order and if any of these bindings fail, the execution will break and jump to the else-block.
The bindings can be followed by an optional where-clause, which gets evaluated only if all bindings were successful. And only if the where-clause evaluates to true, the if-branch gets executed.

if let name = person.name, age = person.age where age >= 18 {  
    println(\(name) is at least 18 years old.)
}

Chain of Love

Good news for all the people who loved nil-messaging in Objective-C. It's still there in Swift and it's called Optional Chaining. Optional Chaining is similiar to Forced Unwrapping but will fail silently. Instead of putting a ! after the optional you use a ?. ? will unwrap the value if there is one and will call the decalared method, property or subscript on it.

class Person {  
    let name: String

    init(name: String) {
        self.name = name
    }
}

let persons = [  
    "Luke" : Person(name: "Luke"),
    "Han" : Person(name: "Han")
]

persons["Luke"]?.name  

Because there is the possibility that a call anywhere in the chain might fail, Optional Chaining will always return an optional value, even if the method called is not. Therefore it's always possible to check if the calls were successful or not.

class Address {  
    let street: String
    let city: String

    init(street: String, city: String) {
        self.street = street
        self.city = city
    }
}

class Guest {  
    let name: String
    let age: Int
    var address: Address?

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

class Hotel {  
    var guests: [Guest] = []
    let name: String

    init(name: String) {
        self.name = name
    }
}

let hotel: Hotel? = Hotel(name: "Grand Budapest")

var guest = Guest(name: "Madame D.", age: 100)  
guest.address = Address(street: "Schloss Lutz", city: "")

hotel?.guests.append(guest)

// Altough the street property is a string,
// when called with optionals chaining it returns
// a String?
let street = hotel?.guests[0].address?.street  

And if you wonder what a method with no return type might return when called with Optional Chaining, the answer is a Void?. Because every method with no explicit return type, implicitly returns Void.

The Curious Case of Implicitly Unwrapped Optionals

I am sure you have seen something like this in Swift code

class MyController : UViewController {  
    @IBOutlet UILabel: myLabel!
}

and asked yourself, hu, whats up with this !. Because when using it, you see no difference to a normal property.
Yes you may guessed it, it is indeed an optional and the reason it has no difference to a normal property is that the runtime will implicitly unwrap it everytime you access it.

The reason this exists is for properties that are not there during initialization (like your outlets for example, which are getting assigned somewhere between -init and -viewDidLoad) but right after it and then never getting nil again. And to save the lazy developer from typing ! explicitly everytime he or she wants to access it, it can be declared as implicitly unwrapped.

Extra Goodie

There exists a very handy operator for working with optionals called the nil coalescing operator (great name to remember btw) written as ??. The first parameter is an optional value and the second is a value of the same type as the optional wraps. When the optional is non-nil it returns the unwrapped value, however if the value is nil it returns the second parameter. This is very great for providing default values.

let defaultName: String = "René Belloq"  
var name: String?

var displayName = name ?? defaultName  
// displayName is "René Belloq"

Basically ?? is doing the same as the following expression.

name != nil ? name! : defaultName  

Conclusion

You saw that Optionals are solving a real problem in a very elegant way. The concept is not new and well proved by other languages. Because every Swift programmer has to work with them a lot, the syntax is held concise and clear and there are good language constructs for everyday use cases such as if-let-bindings and the ?? operator. Keep in mind, optionals are not an annyoing thing you have to deal with in system frameworks but a great tool in your toolbox you should absolutly use.


  1. The Swift Programming Language
  2. Wikipedia: Option Type
  3. http://nshipster.com/swift-1.2/
  4. http://stackoverflow.com/questions/24006975/why-create-implicitly-unwrapped-optionals