PrePitch: Optional variables should require explicit initialization

-111111111111111

I think at least some form of this proposal should be put up for review specially for the tuple case which is just bizarre. I will start another thread about the @Default. Thanks for the question!

Good to know. And yeah, I'd agree, that case is pretty odd. I'd be curious to know if anyone is actually using that as a "feature"

No sure but its an old bug report. [SR-354] Non-optional variable tuple of optional values should not have default value · Issue #42974 · apple/swift · GitHub

Definetly -1, I dont like the idea to add useless code to make explicit an intuitive default

It’s ok to both like and prefer the current implementation, but to call it useless is factually incorrect. Explicit initialization can prevent real bugs, and there is a real semantic difference between uninitialized and nil. There are real, measurable use cases.

Please refrain from stating opinions as fact.

What you mean to say, is that you don’t care much about that difference and that the convenience of implicit initialization far outweighs the costs. Which is a fine position to have. But it doesn’t make the suggested change “useless”.

9 Likes

To be honest, I don't have a single opinion here. If you were to default initialize a value, nil is the most appropriate concept to use. I could even see a case for this to be expanded to encompass all types supporting ExpressibleByNilLiteral, rather than being tied to the ? and ! shortcuts for Optionals.

I do think a rule change around properties needs to take into account lazy properties and property wrappers, both of which also change the perceived behavior of initialization.

Sure, the default is intuitive, but it's inconsistent. Why should sugared optionals be implicitly initialized when nothing else is? Not even Optional<T> which is supposed to be the same thing.

5 Likes

I can see a case for requiring explicit nil for (?) Optionals. For (!) IUOs it would seem very counter intuitive to have to explicitly set them to nil at init time since their semantic purpose is deferred initialization.

4 Likes

For reasons laid out higher up in the discussion.

I’m -1 on this. In my opinion implicitly initializing optionals to nil is intuitive for experienced programmers and beginners.

A lot of my code as well as other code I have seen relies on this feature and removing it would cause a lot of code churn.

3 Likes

Definitely -1 on this. I’d be more inclined to say optionals shouldn’t be able to be made through Optional.

Less boiler plate code, not more.

3 Likes

I have spent quite a lot of time (or at least a lot of commits) removing explicit assignments with nil for optional members the last few months on an inherited code base. I don't particularly fancy the thought of putting all those assignments back, since they do nothing for readability — if anything, they add noise.

4 Likes

Definitely a -1 on this from me, purely from a code-breaking perspective.

I can see this affecting code far and wide, including sources outside of maintained codebases such as blog posts, stackoverflow and tutorial videos (which are likely hard to update). Whilst I see the benefit of it technically being more correct, I don’t believe this outweighs the potential chaos it will cause.

There even is a Swiftlint rule discouraging explicit initialisation with nil: SwiftLint/Rules.md at main · realm/SwiftLint · GitHub

-1
When I set a property as optional I expect it to be nil by default and the code is ready to deal with having nil as a value for that property. I think a linter should provide warnings if it's not explicitly set to nil for those who prefer to have this, but the convenience outweighs the "magic" for me.

1 Like

This could be solved by deprecating rather than removing the current behaviour, and issue warnings at call site, warning the programmer that the implicit initialisation of nil may be unwanted, but still allow it. This behaviour could also be guarded through some sort of environment variable it would be an error in new (or converted) xcode projects, but a warning in older code bases.

Consider this code:

struct Thing: Decodable {
    let field: Int
    let optional: Int?
}

        let json = """
        {
        "field": 123,
        "optional": 999
        }
        """.data(using: .utf8)!
        let thing = try! JSONDecoder().decode(Thing.self, from: json)

Thing(field: 123, optional: Optional(999))

Now, change the declaration of optional so that you don't get a warning from the proposed change:

    let optional: Int? = nil

Now you get:

Thing(field: 123, optional: nil)

No one has suggested this.
Firstly, let already works correctly. Secondly, if it was declared as

var optional: Int?

You still wouldn't get a warning on this line. However, you would get a warning in your initialisers that you "Return from initializer without initializing all stored properties"

Consider this example:

struct Thing: Decodable {
    let field: Int
    let optional: Int?

    init(field: Int, optional: Int?) {
        self.field = field
    } // error on this line
}

Then replace the lets with vars and observe that the error goes away. This proposal suggests that they behave the same.

How do you mean that "let already works correctly"?

This proposal would add init boilerplate for no particular gain.