Jeremy W. Sherman

stay a while, and listen

Pervasive use of Optional in Swift is penance for nil

If you’ve looked to do anything significant with Swift, you’ve likely had to fall back on our old friend, Foundation, and likely also some newer friends in the form of other core Apple frameworks.

One thing you cannot miss with this legacy APIs is the pervasive use of optional types.

Thanks to them, we still get to angst about the billion-dollar mistake of nil, only now we get to pay a steady syntax tax throughout our codebase.

It is in light of this that I read a snatch of a comment by Dr. Robert Harper with some interest:

Your emphasis on whether the nth argument to that function/method is an option or not does not do justice to the real issue, which is what Yaron Minsky calls making undefined states unrepresentable (or words to that effect).

[…]

It is of course possible to do C-like or “pythonic” programming in ML using options instead of the “null pointer”, but that’s not the way to write good code […]. What you want is

  • types to express the correlations between components, these are called sums, and
  • pattern matching to explicitly match the cases that are legal and allow the exhaustiveness checker to warn you when you’ve missed a case, either by mistake or by design or as a consequence of evolution of the code.

I am afraid we know for a fact that legacy Objective-C APIs are not up to this challenge. Surprise exceptions and undocumented behavior on nil input will be with us for some time.

It is an open question whether Swift-native APIs will be written to support and lead us by example to that latter style of programming.

The way the Swift book punts in the face of a data source protocol with two options for providing data is not encouraging to this end:

NOTE: Strictly speaking, you can write a custom class that conforms to CounterDataSource without implementing either protocol requirement. They are both optional, after all. Although technically allowed, this wouldn’t make for a very good data source. (“Optional Protocol Requirements”)

Such an aside would have been the perfect time, not to shrug out, “oh, they are both optional, too sad, but what are we to do?”, but instead to explain how an enumeration could be used to admit a delegate implementing precisely one or the other but not none and not both.