Here to add my -1, especially for the IBOutlets case, and to keep the syntax as noise-free as possible
I think IBOutlet should provide default or delayed initialization via the new property wrappers feature. In that case it would not even have to be an optional. I’m asking on the other thread about this.
+1
Hand writing = nil
is not a burden and making the following code compile would be a nice side benefit of the consistency we'd gain.
let foo: String?
if condition {
opt = "bar"
} else {
opt = nil
}
I'm -1.
I think there's an argument to be made on both sides, but this would be a heavily source breaking change, (though admittedly with a fairly easy fix). There are also style guides / linters that have this behavior as preferred.
It is odd that var someValue11:Optional<String>
doesn't default to nil, but that seems more like a bug than intentional.
Personally I prefer the cleanness of not having to set something that has a clear default.
There is no avenue that I know that we can approach Apple to change the behavior of their SDK other than bug reports but I don't why they could not move to a world were IBOutlet and friends use property wrappers.
@IBOutlet var label: UILabel // Okay! IBOulet using property wrappers for delayed init
This could also be a linter thing, especially since we apparently have people pretty strongly on both sides of the question. I've started working on a pull request to add this to SwiftLint, as an option on the existing redundant_optional_initialization
rule which currently enforces not initializing optional var
declarations with nil.
Assuming SwiftUI isn't going to be pushed so much that the old APIs will keep being updated with that kind of feature, I can't see it happening till next year. Assuming that's how it should work, (as we don't know the internals of Interface builder), I would imagine they would wait till propertyWrappers feature won't change.
I’m very supportive of this idea, I always found it confusing and inconsequent that optional vars of all things in the language had automatic initialisation.
+1 Less magic. Explicit over implicit. Bring it on!
I'm having a hard time articulating why, but I'm very much -1 on this.
nil
is a "concept of zero" — where zero is something that denotes nothingness. nil
is just another way of saying .none
, but so is... nothing, as in, not specifying nil
. I guess one of the reasons why var some: Int?
feels correct is that you don't have to write out nil
because it was already nothing to begin with.
With this context, I believe this is the special case for implicit initialization.
And arguments like...
...seem to contradict the rationale behind some great new features in Swift like @propertyWrapper
s and @functionBuilder
s where "magic" is promoted.
By this reasoning, shouldn't Int
implicitly be 0? What about Array
and []
? String
and ""
?
Granted, Optional
is an extra special type in Swift, but not much more than the ones I listed above.
I don't think so. Those types don't have the concept of "non-existence" baked into them. 0
is a valid integer just as much as 42
is, and an empty array is still an Array
(same goes for String
). They exist. nil
, .none
, are our way of saying that something explicitly doesn't exist.
It definitely is an extra special type and should be treated that way.
When designing APIs, authors are often confronted with whether or not to use nil
or the empty string/array to denote no results. Most of the time, it doesn't matter which is chosen. Int and 0 were a poor example, but ""
and []
are both equal representations of nothingness for their respective types, just like the .none case is for Optional.
Sure, that's fair, but the semantics of an empty array []
or a nil
are just that: semantics, and should be left to the API designers to define. Most of the time it doesn't matter, but sometimes it does, depending on semantics.
Regardless, [] == nil
will always be false
. []
exists, it's something.
Right, I'm not arguing that nil == []
, that's madness. I am saying that nil
and Optional
have the same relationship as []
and Array
. Neither should get implicit initialization to their respective empty values.
This already compiles (assuming that the opt
s in the branches are meant to be foo
s). The implicit initialization does not apply to let
.
let foo: String?
print(foo ?? "missing") // error: Constant 'foo' used before being initialized
But like you said, Optional
is a special type. Its nothingness is true nothingness in Swift, which is why var some: Int?
is already correct and shouldn't need to be specified by explicitly declaring = nil
. (Or at least this is why I think it feels correct. Again, it's difficult to articulate, so thanks for bearing with me.)
Hmmm, so it does. I made a mistake there. Thanks.
If nil
is "true nothingness," then how would you describe an uninitialized optional value, which entails the absence even of nil
?
(And then consider the optional value being of type Optional<Never>
.)
Again, as unsatisfactory as this might sound, it's a special case in Swift and should be (and already is) treated that way. var some: Int?
is already an initialized Optional<Int>
(as .none
) which is as "nothing" as "nothing" gets in Swift. By specifying "nothing" you get "nothing" (nil
, .none
).