Optional array vs. empty array in Swift

Interestingly enough, we have recently had few discussions regarding this very same question at work.

Some suggest that there are subtle semantic differences. E.g. nil means a person has no children whatsoever, but then what does 0 mean? Does it mean "has children, the whole 0 of them"? Like I said, pure semantics "has 0 children" and "has no children" makes no difference when working with this model in code. In that case why not choosing more straightforwards and less guard-let-?-y approach?

Some suggest that keeping a nil there may be an indication that, for example, when fetching model from backend something went wrong and we got error instead of children. But I think model should not try to have this type of semantics and nil should not be used as indication of some error in the past.

I personally think that the model should be as dumb as possible and the dumbest option in this case is empty array.

Having an optional will make you drag that ? until the end of days and use guard let, if let or ?? over and over again.

You will have to have extra unwrapping logic for NSCoding implementation, you will have to do person.children?.count ?? 0 instead of straightforward person.children.count when you display that model in any view controller.

The final goal of all that manipulation is to display something on UI. Would you really say

"This person has no children" and "This person has 0 children" for nil and empty array correspondingly? I hope you would not :)

Last Straw

Finally, and this is really the strongest argument I have

  • What is the type of subviews property of UIView: it's var subviews: [UIView] { get }
  • What is the type of children property of SKNode: it's var children: [SKNode] { get }

There's tons of examples like this in Cocoa framework: UIViewController::childViewControllers and more.

Even from pure Swift world: Dictionary::keys though this may be a bit far fetched.

Why is it OK for person to have nil children, but not for SKNode? For me the analogy is perfect. Hey, even the SKNode's method name is children :)

My view: there must be an obvious reason for keeping those arrays as optionals, like a really good one, otherwise empty array offers same semantics with less unwrapping.

The Last Last Straw

Finally, some references to very good articles, each of those

  • http://www.theswiftlearner.com/2015/05/08/empty-or-optional-arrays/
  • https://www.natashatherobot.com/ios-optional-vs-empty-data-source-swift/

In Natasha's post, you will find a link to NSHipster's blog post and in Swiftification paragraph you can read this:

For example, instead of marking NSArray return values as nullable, many APIs have been modified to return an empty array—semantically these have the same value (i.e., nothing), but a non-optional array is far simpler to work with


The ability to choose between an empty array or an optional gives us the ability to apply the one that better describe the data from a semantic point of view.

I would choose:

  • An empty array if the list can be empty, but it's a transient status and in the end it should have at least one element. Being non optional makes clear that the array should not be empty
  • An optional if it's possible for the list to be empty for the entire life cycle of the container entity. Being an optional makes clear that the array can be empty

Let me make some examples:

  • Purchase order with master and details (one detail per product): a purchase order can have 0 details, but that's a transient status, because it wouldn't make sense having a purchase order with 0 products
  • Person with children: a person can have no children for his entire life. It is not a transient status (although not permanent as well), but using an optional it's clear that it's legit for a person to have no children.

Note that my opinion is only about making the code more clear and self-explainatory - I don't think there is any significant difference in terms of performance, memory usage, etc. for choosing one option or the other.


I'm going to make the opposite case from Yordi - an empty array just as clearly says "this Person has no children", and will save you a ton of hassle. children.isEmpty is an easy check for the existence of kids, and you won't ever have to unwrap or worry about an unexpected nil.

Also, as a note, declaring something as optional doesn't mean it takes zero space - it's the .None case of an Optional<Array<Person>>.