Lucas Derraugh Lucas Derraugh - 1 month ago 5
Swift Question

Swift nil has a numeric value?

This is valid code in Swift:

println(nil < 1)

And the output will be true, likewise

println(nil > 1)

will be false (the number 1 is arbitrary, you can do the same for -1 and probably something else). The reason I ask is because I saw some code that tried to compare
to a numeric value and it compiled, which seems wrong considering

My question is, should this be valid syntax in Swift? If so, what is the numeric value of nil?


Looks like Swift Evolution tackled this issue by removing the optional comparison operators. This is no longer an issue in Swift 3.0 as it doesn't compile.


I believe what is happening is that the literal 1 is being implicitly typecast to the Int? type by the comparison to nil. For those who aren't used to Swift, I'll explain a little further. Swift has a concept called "optionals", which can either have a value or be nil. (For anyone familiar with Haskell, this is basically the Maybe monad.) It's illegal to assign nil to a variable that wasn't explicitly defined as optional, so let i: Int = nil will be rejected by the compiler. This allows for several benefits which are out of the scope of this answer, and it's a rather clever way to do it.

What's happening here, though, is that the literal 1 is a valid value of several types: Int, Int32, Int64, UInt32, UInt64, etc., etc., etc. And it's also a valid value of the optional versions of those types: Int?, Int32?, etc.

So when the Swift compiler sees a comparison between a literal value and nil, it tries to find a type that both these values would be valid for. 1 is a valid value of the Int? type, and nil is also a valid value of the Int? type, so it applies the comparison operator with the type signature (Int?, Int?) -> Bool. (That's the comparison operator that takes two Int? values and returns a Bool). That operator's rules say that nil values sort lower than anything else, even Int.min, and so you get the result seen in the OP's question.