In many cases, a forced unwrap, simply using !,
is the right way to unwrap an optional value. The problem isn't with !
existing or being used in code, especially when it's established that an optional cannot be nil at the point of !
use. The problem is that the compiler is guiding newer users down a path of using !
in an extremely unsafe way because it cannot contextualize the !
with regards to developer intent.
New users, who may be unfamiliar with guard let
and if let
, which provide exit patterns and conditional binding of unwrapped values, are stuck in the mode of "what do I need to do to make this code compile?" Stack Overflow, the dev forums, IRC, various slacks, etc are overflowing with examples of terrible !
use. Those of us who mentor and teach see reflexive !
insertion "just to make things work" propagate because of the fixit availability.
This is not a reflection of !
being an antipattern. This is due to a problem with compiler tooling and specifically the "moral hazard" of its fixit.
I personally want to introduce !!
the unwrap or die operator, which asserts that an item cannot be nil and then provides a succinct in-code reason why the optional must be .some
. Using !!
creates better in-context documentation at the point of use both for experienced and naive users.
In addition experienced users can always use !
because it is and will continue to be an important part of the Swift programming language.
I don't want this thread to be a referendum on "Should I eschew !
in my code?". You shouldn't. The points I'm posing are these:
- The Swift compiler lacks a holistic understanding of developer intent.
- The
!
fixit should not be used as a bandaid to make things compile. - Experienced developers can distinguish whether an unwrapped value reflects an overlooked unwrap or it is guaranteed to never contain nil.
- Inexperienced developers, unless they're moving from a language with similar constructs, usually will not. They're focused on getting past a compilation barrier, without realizing the hazard of nil values at the point of use.
- The fixit is a modest courtesy for experienced developers.
- The fixit is a moral hazard for inexperienced developers.
Given Swift in its current form, the choices that should be considered are:
- Removing the fixit entirely but retaining the information in the error message.
- Removing the fixit and retooling the error message to offer a link to optional best-use tutorials.
- Offering a better fixit by adopting
!!
.
I don't think "overhauling the compiler to guess user intent" is on the table nor "remove !
from the programming language".