Optionals and if-let

Natasha posted a article a little over a week ago: http://natashatherobot.com/swift-unused-optional-value/. I agree with her initial feelings, "This immediately stood out as "wrong" to me."

Basically she was talking about this:

var someOptionalVar: String? = "something there"

if someOptionalVar != nil {
    // just need to check for the presence of a value
}

I don't like this. It just doesn't feel semantically correct. The optional is not nil, it specifically has a value of None. I've never liked this syntax; I've talked about it before – thankfully the bool comparison has been lost, but the nil check still sits wrong with me.

Another example:

let f‚ÇÄ: Bool? = true
let f‚ÇÅ: Bool? = false
let f‚ÇÇ: Bool? = nil

let fn = [ (f‚ÇÄ, "f‚ÇÄ"), (f‚ÇÅ, "f‚ÇÅ"), (f‚ÇÇ, "f‚ÇÇ")]

for (f, label) in fn {
    if f == nil {
        println("\(label) has no value")
    }
    if f != nil {
        println("\(label) has a value")
    }

    if let fv = f {
        println("\(label) = \(fv)")
    }
    else {
        println("\(label) = nil")
    }

    switch (f) {
    case .Some(_):
        println("\(label) has a value.")

    case .None:
        println("\(label) has no value")
    }
}

It's a bit annoying that we have so many ways to check for the presence of a value in an optional. I find languages that have multiple ways of achieving the same thing end up being confusing, especially as more features get added. It's unnecessary complexity that adds over time. Natasha already pointed out the multiple discussions of people doing it different ways.

I also prefer a different way:

func hasValue<T>(value: T?) -> Bool {
    switch (value) {
    case .Some(_): return true
    case .None: return false
    }
}

for (f, label) in fn {
    if hasValue(f) {
        println("\(label) has a value")
    }
    if !hasValue(f) {
        println("\(label) has no value")
    }
}

There is no ambiguity here, there is not transparent conversion between nil and .None, and most importantly to me, the code is always extremely obvious.

Optionals and if-let