Falsiness in Swift


There is really interesting article by Khanlou about falsiness. I have found myself in situation trying to do this in Swift:

var optional: String? = // ... some logic
	if optional {
		// do something if not nil
	}

And compiler didn’t let me do it. So if we make Optional conform to BooleanType this should work just as I expect it to.

But do I really want to do that?

While this is definitely useful in some situations I think it may be source of bugs in others.

We might think that it is reasonable for Int to be supported in if statement. In the end, that works in Objective-C as well.

extension Int: BooleanType {
    public var boolValue: Bool {
        return self != 0 // not sure what to do here
    }
}

if 1 {
    print("this is probably what we want")
}

if 0 {
    print("not executed")
} else {
    print("this is probably what we want as well")
}

if -1 {
    print("but this is a bit weird")
}

While this might be what someone expects, I think it is definitely not obvious and might confuse someone. I would rather have explicit check.

It becomes really confusing when we try to use it with if let construct:

let empty: String? = ""
if empty {
    print("i am not executed")
}

if let e = empty {
    print("i am executed")
}

Usage with dictionaries might as well give us some unexpected results:

extension Dictionary: BooleanType {
    public var boolValue: Bool {
        return !self.isEmpty
    }
}

let countryDescriptions: [String:String] = ["USA" : "", "Croatia" : "Very beautiful"]

if countryDescriptions["USA"] {
    print("we have that country")
} else {
    print("we don't have that country")
}

if let description = countryDescriptions["USA"] {
    print("now we have that country")
} else {
    print("we still don't have that country")
}

This is also something that new team member can’t know if he is not told or if he doesn’t spend some time investigating code base. It adds extra mental overload where you need to thing about what it means for type to be falsy.

Conclusion

Generally, I don’t think this is bad but I do think it is not got fit for Swift. I guess these kinds of things are differences between languages such as Ruby and Swift. Ruby gives us convenience and Swift gives us safety. What you like more depends on you.