On chains, nils, and quiet failures

My take is: don't do that at all (except in rare circumstances).

  • In Obj-C days, we did this all the time (with a null pointer standing in for a Swift optional). We'd write a slab of code ignoring nulls, and check at the end whether we got a non-null result. This worked well in Obj-C, provided you'd learned to avoid the pitfalls, because ignoring nulls was demonstrably harmless in many cases where an eventual null or non-null result was all you needed.

  • I don't recommend "carrying" optionals like this through Swift code, though, because Swift Optional is a semantic thing, not just a side-effect of the dereferencing mechanism. Swift code seems easier to read and understand if you handle nil-valued optionals when they first appear (using guard and if, for example).

  • In other words, the beauty of Swift optionals is that they allow you to elegantly eliminate optionals and extensive use of ? from most of your code. You don't need to reason about whether propagating them is safe or sound. Something like:

    guard let baz = foo?.bar?.baz else { … } // It's clear why/when we're not quxing here
    baz.qux() // We know here that we're really quxing that baz!
  • So, I'd suggest that a new postfix operator would have the wrong effect on code writing, by encouraging the carrying of optionals instead of their elimination.

The cases where you might genuinely want to carry an optional value forward are when you're carrying or computing a value to be stored in a property which is itself optional (but often not even then).

7 Likes