[swift-evolution] Propagating Optionals

Trans transfire at gmail.com
Sun Sep 25 15:19:59 CDT 2016


As I've been learning Swift recently, one aspect of the language
jumped out at me with a "code smell". Namely, the way Optionals are
handled. For starters, just consider how long this chapter is:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html
That's pretty beefy for something on the surface is pretty simple.

More concretely, consider the example given:

    class Person {
        var residence: Residence?
    }

    class Residence {
        var numberOfRooms = 1
    }

    let john = Person()

    let roomCount = john.residence.numberOfRooms

    // error: value of optional type 'Residence?' not unwrapped; did
you mean to use '!' or '?'?

As general rule of thumb, whenever I get an error and the system tells
me what I probably meant, that is a pretty good sign the system isn't
doing all it can for me and making me jump through an unnecessary
hoop.

Basically "john.residence.numberOfRooms" is a completely wasted
expression -- it's meaningless. You have to put a `?` or `!` in there
to get anything useful. I can't see any good reason for that.
"john.residence.numberOfRooms" could just behave one way or the other,
either as if the `?` were there, or the `!`. And of the two, the
obvious choice is `?` because... I already told the program it the was
optional in "var residence: Residence?".  I said it was optional, and
yep I meant that. (Reminds me of the old retort "did I stutter?")
Thus, if I try to assign it to something else it too should be
optional. If I want it to be otherwise I'd add the `!`.

Making this change would just simplify a whole mess of code and about
half that chapter would all but vanish.

In addition, seeing that `!` acts a short-circuit to error, it would
be nice to have something equivalent for fallback value. We can't use
`??` b/c it doesn't chain, though maybe it could be made to? And I'd
rather not reuse `?.` here  (for reasons I can explain later). Maybe
`:` is a good choice? In any case, exact syntax aside,

    let homelessShelter = Residence()
    let roomCount = john.residence:homelessShelter.numberOfRooms

Now, roomCount will not be optional, because there is a guaranteed value.

I think simplifying Optionals this way would be a good fit for Swift,
making this part of the language a whole lot cleaner and clearer.


More information about the swift-evolution mailing list