Optionals are not very “Swift”

Swift is a great new language: a compilation and evolution of the best languages. However, Swift’s use of optionals seems more like a devolution.


I would guess that many programmers, including the very experienced, have found these optionals to be more of a nuisance than a help. Nil is basically a value like any other value. If an object (and everything is basically an object) returns a value of nil, a good programmer deals with it just as they would deal with any other returned value. If your code crashes, then fix it, just as if it crashed for any other reason.


Yes, there are probably some arguable underlying reasons for the inclusion of optionals into Swift, but these mechanics should be dealt with internally in the language and not be passed on to the programmer. After all, Swift is designed to be a high-level language, but the inclusion of optionals drags it down and ruins the visual beauty of the code.


I really appreciate the work and thought that must have gone into this language; it’s a pleasure to work with, a true gem. And I'm glad that it’s to become open-source. But make Swift really swift and lose the optionals; we can “handle” it!

These sorts of discussions aren't likely to go anywhere, because they come down to dueling preferences, even when there are technical considerations, too. But one thing you said struck me:


>> a good programmer deals with it just as they would deal with any other returned value


If you accept that (as do I), I don't see why that weighs against optionals. They simply force all programmers to "deal with it", and you seem to want to applaud that concept.


The difference with a language (and runtime) that has explicit optionals is that failure to deal with it is going to cause an immediate crash at the point where the nil arises, not some unpredictable time later as currently. The price you pay for this consistency is a more complex source syntax, but that probably can be leveraged to help you deal with it more conveniently, after you've had time to get comfortable.


Anyway, as far as Swift has concerned, this ship sailed long ago.

Hello QuinceyMorris,


The reasons you pointed out for adding optionals are very good reasons I believe, and especially refering to critical systems where hidden future crashes could end-up creating unintentional harm, but why stop at "enforcement" of Nil values. This enforcement to avert crashes (current or future) could be applied to other valid areas in coding as well. My point is simply to leave the responsibility with the programmer and their error checking and unit testing systems they have (or should have) in place to do their job. I certainly wouldn't want to overly rely on optionals for a false sense of security.


For me it's a case of where to draw the line. Certainly compiler warnings could be used instead. And then there's the new do-catch block in Swift 2.0 (like try-catch in Java)


But I think the ship may still be sailing on this; I would guess (and only a guess) that we could see optionals removed in the future in favor of a warning system.

>> I would guess (and only a guess) that we could see optionals removed in the future in favor of a warning system.


I bet you $20 that they won't be. (I'd actually bet $1,000,000, but you wouldn't be crazy enough to take that bet, right?)


BTW, I just parsed your forum user ID. Are you a former/simultaneous C# user? If so, I don't wonder that you hate optionals. The literally half-assed implementation there (well, not literally, but literally bifurcated: explict for value types, implicit for reference types) turns out to be unbearably painful, IMO.

No experience with C# (just a little C). Actually (now this is going to date me) my work experience started with the IBM AS/400 now called the IBM iSeries mid-range business computer using RPG and RPGILE. Rather dry stuff heavy on database work but paid the bills. Then developed in Java and then onto Objective C and finally landing on Swift.


By the way, I'd take the million dollar bet but, being the gentleman that I am, I decline, do to the fact that I hate to see a person cry 🙂

There's a theory-based answer and a practice-based answer here, and they both come to the same conclusion.


Practice first: there are basically three ways to deal with unexpected missing values. You can crash (CF style), do nothing (ObjC style), or refuse to compile (Swift style). We've found from long experience that the first and second tend to lead to crashes and unintuitive logic errors in real apps and frameworks. Tony Hoare, who invented null references in 1965, refers to them as his billion dollar mistake.


Theory answer: the "inhabitants" of a type are the possible values of that type. So the inhabitants of Int are the set of integers that fit in its size, and so on. nil is special in languages like Objective-C because it's automatically an inhabitant of *every* reference type. So when you say "this is an NSString" you're actually saying "this is an NSString or nil" and so on. Allowing people to specify "this is an NSString" separately from "this is an NSString or nil" allows them to be more precise about what they mean.


I suspect (though I don't know for sure of course) that what you're actually running into is that far too many APIs return optionals currently. This is something that we've been improving as we update the APIs for Swift in El Capitan and iOS 9 by doing things like returning empty NSArrays instead of nil. Ideally in your programs, most things will be non-optional, and the remainder will be cases where you would have needed code to handle it in ObjC too.

I really like, and appreciate, your simple and eloquent explanation of optionals.


I draw attention to the concept of allowing people to be more precise about what they mean in the case of the state of an object. I believe, this tries to fix or prevent a problem but causes confusion because it doesn’t reflect the real world.


Most things can be broken down into 4 basic categories (from automobiles to marriages) in the real world that reflect in OO design and implementation.

  1. a cup has a design on paper (code)
  2. a cup is manufactured (an instance)
  3. a cup is used (actions (state changes: full, empty))
  4. a cup is broken (null reference)


So to say, “this is a cup” can refer to all 4 categories. This means any object can have a null reference (unusable), and I would think most programmers understand this. Consequently, to say, “this is a cup or not (null)” is where the confusion comes in. The programmer is forced to decide whether the cup could break (be stolen or become unusable) or not, when before, they always assumed it could be. So they wonder, “what are they getting at… why do I need to specify the obvious”. Not only that, but which APIs have optionals and which don’t? Is there just a quick shortcut to circumvent this added factor into my code design? Could not a compiler warning bring this possibility to my attention?


This “enforcement” engenders a reaction among programmers to use shortcuts or simplifications to circumvent it. So in some cases (maybe many) it’s not being used as it was -ideally- intended.


If Swift assumed all objects must have an instance and that that instance can be null, it would not only reflect the real world better, but would remove a layer of complexity in an already complex coding environment (especially when it goes open-source).


Having said that, I like Swift and hope it takes root far and wide when it goes open-source. I am also encouraged by your pointing out the progress in reducing the APIs that return optionals. And yes, your last paragraph, I think, reflects what programmers are experiencing.

Representing a broken cup as nil, rather than an error or alternate state of some sort, seems like an inaccurate modeling of the situation. nil would generally represent "no cups", or the absence of a cup. Writing a "drink(fromCup:)" method that accepts no cups to drink from would be confusing. So when you write that method, you'd specify the cup as non-optional, and avoid accidentally having thirsty users. Forcing API designers to decide things is more work for the API designer, but less work for everyone that wants to use that API correctly.


In practice, what we've found is that each time we introduce stronger static verification like this in Objective-C (clang static analyzer, nullability annotations, generics, bridging annotations, printf format checking, the list goes on and on), it catches real bugs in shipping programs. Correctness is worth a little inconvenience, especially when it comes along with increased expressiveness.


That said, if there are places that appear to be unnecessarily inconvenient (making you write code to handle something that will never happen, for example), or if there are things that could make dealing with optionals less inconvenient (Swift's ?. chaining syntax, and ?? default value syntax being great examples of ones already in place), please don't hesitate to file bug reports!

Optionals are not very “Swift”
 
 
Q