Perhaps the single most defining feature of Swift is its overall focus on safety. This safety covers the type system, naturally, but also importantly assists the developer in ensuring the existence of a value at a property’s point of use. In those situations where it makes sense for a property to contain no value at all, the Optional type (along with a few handy pieces of syntactic sugar) allows us to safely check for the presence of a value, and then act in accordance with the needs of our app. And in all other cases (the default, ideally), we can make use of non-Optional types and avoid having to worry about whether our properties contain usable data or not, because the compiler ensures that they must.

And this is all pretty amazing stuff! But Swift’s focus on safety has also generated a troubling mentality in the community, by which a certain feature has been deemed “unsafe,” treated as a near-universal code smell, and had its (in my view) totally valid and essential meaning dismissed. I’m talking, of course, about the dreaded forced unwrap.

First, let’s take a quick look at some code snippets illustrating all of the major ways to deal with Optional types. There’s if-let unwrapping:

Nil coalescing:

Optional chaining:

Forced unwrapping:

The argument against forced unwrapping turns upon the notion that it is the only inherently unsafe method for unwrapping a value that may be present within an Optional. Which is to say, if you attempt this method and the Optional contains no value, your app will crash.

But what I’d like to suggest — and what I feel gets lost in all of the (well-intentioned) mania about safety within the Swift community — is that forced unwrapping, like all of the other unwrapping methods, conveys a unique and valid meaning to the reader of a piece of code, and that we do ourselves a disservice by suggesting that forced unwrapping is merely a product of reckless corner-cutting or laziness on the part of the programmer. To illustrate, let’s walk through the implied meanings of the unwrapping methods:

If-let: “I want to perform some (perhaps complex) action with the value contained in this Optional, so if it contains a value, do something with the value, otherwise perform a different action.” (There need not be an otherwise here, but I’ve included one for the sake of completeness.)

Nil coalescing: “I fundamentally care that this expression resolves to a value, so if this Optional type contains a value, use that value, otherwise use some default value of my choosing.”

Optional chaining: “If this Optional type contains a value, then access the value, but at the end of the day, I don’t really care whether this gets done or not, because it’s not essential to the core operation or functionality of the program.”

Forced unwrapping: “This Optional type may not begin with a value, but by the time I use it here, I expect it to have a value, and beyond that, it absolutely needs to have a value in order for the core functionality of my program to be intact. I would expect my program to crash if there is no value, because there is no way to handle this situation gracefully.”

I’ve noticed that many in the Swift community suggest in rather strong terms that forced unwrapping is to be avoided at all costs, even going so far as to recommend not using implicitly unwrapped IBOutlet properties (which are, for all intents and purposes, guaranteed by the system to be hooked up properly and accessible upon the loading of an app). The underlying assumption seems to be that the most important thing, at all times, is to ensure that one’s perceived competence as a programmer is always protected, and that the best way to do this is to make it impossible for your program to crash at all. Because forced unwrapping allows for runtime crashes to occur, it’s written up as a forbidden art, and its underlying meaning is dismissed.

Students of Swift are often told to replace forced unwrapping with optional chaining. But if we investigate what you are telling yourself and other readers of your code when you use it (“It literally does not matter whether this expression resolves or not”), it becomes clear that this is often not the meaning we intend at all. I’d wager that, much of the time, we do actually care whether the expression we’re writing resolves to a value, a successful method call, etc. The core functionality of our program depends on it. If this is the case, doesn’t it make more sense, in terms of the meaning being conveyed to ourselves and others, to use forced unwrapping? To say, in other words, “Yes, I fully expect there to be a value here, and if there isn’t one, that means there has been a catastrophic failure”? It seems to me that this is an extremely useful bit of self-documentation.

Which isn’t to say that forced unwrapping should be commonplace throughout your average program. I wouldn’t hesitate to categorize this as a code smell if it’s clear that a program is absolutely littered with forced unwrappings which could have been eliminated via more elegant design. Moreover, one’s expectation that a force unwrapped Optional will contain a value at its point of use should not be a matter of wishful thinking, but ideally the result of extensive testing, as well as a keen understanding of the program’s flow.

The argument I’m making is that, before we render a language feature taboo in the name of “safety,” we should first pay attention to what its meaning is, and to what we potentially lose by dismissing it wholesale.

Edit (7/19/2016): It’s worth noting that I’m not trying to recommend “best practices” or dictate what should or should not fly on a large team project written in Swift. There clearly do exist good reasons for wanting to minimize or stay away from forced unwrapping entirely. My point is directed more at the notion of evaluating what we mean by utilizing an unwrapping method, and to acknowledge that forced unwrapping means something specific, unique, and genuinely useful in relation to the other methods at our disposal. We should be teaching people this meaning, not concealing it in the assertion that forced unwraps are a dark art.

Another point I’m trying to make is that we sometimes suggest bad practices (for example, that people use optional chaining even if they don’t intend for non-execution to be a valid outcome) merely because they won’t directly cause a crash, and that this is a deeper ramification of putting the meaning of our code on the back burner, in favor of a safety-first mentality.