Tuesday, July 15, 2014

nil is now a convertible literal!

In doubly-optional values, I raised a number of issues with the way Swift handles nil.

In brief, when you have a type T??, there are many cases where you can't clearly distinguish between a T?? value that happens to be a T? nil vs. a T?? nil (in Haskell terms, between a Just Nothing and a Nothing). And most reasonable attempts to deal with that were either impossible to write, or led to compiler crashes or incorrect behavior.

It looks like part of the problem was that trying to handle nil a la C++98 NULL just didn't work right. You can't let nil be a value of every type, you can't let it be a value of a special type that's comparable to and assignable to every type, and you definitely don't want it to be implicitly convertible everywhere, so… what can you do? Well, that's exactly the same problem they solved for the number 0. 0 has to have a type, not every type; int shouldn't be comparable and assignable to every other numeric type (at least not with the other design choices they've made elsewhere), you definitely don't want int to implicitly convert to Int16 or Float32, and yet you want to be able to initialize non-int variables with 0, so… what can you do?

The solution for int was to create a new IntegerLiteral type, and a protocol for defining types that can be initialized with integer literals. And the same goes for float literals, string literals, and a few other types—most notably, array and dictionary literals.

And it looks like, with beta 3, they've gone with the same solution for nil; it's a singleton of a new NilLiteral type. Although I haven't gotten beta 3 installed and running yet, it seems like this should at least make the problem solvable, if not solve it.

I also like spelling Array<T> as [T] and Dictionary<Key, View> as [Key:View], and a few other changes. But of course this means that some of my existing code that worked in beta 1 and beta 2 (product, optionalize and friends, etc.) needs to be changed. And this doesn't seem to be the only breaking change. So it looks like the promise of no significant, code-breaking languages changes after beta 1 was a bit premature. Also, the stdlib header visible in Xcode seems to be even farther from what the compiler actually uses (and the error messages refer to) than in beta 2. So, maybe it's a bit early for me to be trying to implement a complete library, and I should instead just build one or two functions as a proof of concept that I can keep tearing apart and re-doing, then worry about writing something useful once the compiler and library are actually ready?

No comments:

Post a Comment