PrePitch: Optional variables should require explicit initialization

Hi Team,

I wanted to bring up the current magical behavior of Optional auto initialization to nil when using ?

Currently in swift you can declare an Optional variable in this way

var foo: String?
print(foo) // prints nil

swift will automatically assign .none to the value. The above is somewhat equivalent to the below code.

var foo: String? = nil // .none
print(foo) // prints nil

but this behavior is only available when using ?. The below does not work.

var someValue11:Optional<String> 
// print(someValue11) // error: variable 'someValue11' used before being initialized 

I think this behavior is confusing specially when dealing with implicit unwrapped optional.

var someValue33:String!
_ = someValue33 + "?") // Boom Crash. No different from an uninitialized variable error

I propose that we deprecate this to make swift more consistent.

var foo: String?
// print(foo) // error: variable 'foo' used before being initialized. <Insert fixit here to add = nil>

What does the community think?


I don't see how the calculus has changed. It's a trivial rule to learn and saves more than it hurts.


It's also confusing because it applies to local variables but not to properties.

It applies to var but not let, both for local variables and properties.


Well the fact that I got that wrong just shows how confusing it is! :slight_smile:


I'd be very happy to see the implicit initialization removed. In addition to the issues mentioned in your pre-pitch, I want

  var x: Int?
  if b {
    x = 1
  } else {

to tell me that I haven't initialized x on all paths like it does for any other type.


Undocumented extension of this feature: tuples of optional types are default initialized as well.

var x: (Int?, ((Bool?, Int?), Int?))
print(x) // prints (nil, ((nil, nil), nil))

If we remove this behavior, we should document that the tuple behavior is removed as well.


This would clean up a lot of implicit rules and edge cases in the compiler! :smile:

1 Like

i know what the rule is but at this point i’ve taken to just always writing out the nils to avoid confusion with let deferred initialization. will attest that i too find this pretty confusing.


I've run into problems a handful of times where I forgot to set an optional property during initialization because it defaulted to nil. I'd be happy to see this rule removed mainly for that reason, but also because it's a special case rule that doesn't pull its weight in terms of convenience imo.


Then make that property non-optional? Perhaps you are tracking some state where, instead of an optional, it would be better to use your own enum with cases named after the states + associated values for the data.

Since most people above seem positive to this pitch, just want to add a -1.

I agree that a custom enum is sometimes more appropriate than an optional, but not always. In cases where an optional is more appropriate, I wouldn't want to create an enum just to protect against this issue.


I'm +1 on this. I don't feel it pulls it's weight, and I agree with @taylorswift about the let deferred initialization issue.

1 Like

+1 as well for the reasons above.

I don't normally post here, but I also wanted to balance things out a bit with a -1.

Personally, I find it convenient to declare and initialise optionals with nil in one go (sort of like the opposite to type inference for non-optional variables, i.e. writing out the type instead of the value). Despite the anecdotes above, the rule also seems straightforward.

(Equally, I'm one of the weirdos that liked doing var x = Int?() in the Swift 2 days, so make of that what you will!)


to protect yourself from missed initialisation in that case when you have if else I use let

it is like init with default parameters but for Optional, isn't it?

+1. There is no reason for a special case implicit initialization.



With this change, would all @IBOutlets have to be explicitly initialized to nil then?

@IBOutlet var label: UILabel! = nil