Pitch: Remove default initialization of optional bindings

Hi all,

Right now, the following two declarations are equivalent:

struct S {
  var x: Int?
}

struct S {
  var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava

3 Likes

Hi all,

Right now, the following two declarations are equivalent:

struct S {
var x: Int?
}

struct S {
var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

I don’t have too strong an opinion on this, leaning towards being supportive. That said, I think you underestimate the source breakage it will cause. I have seen a lot of code this change will break (albeit in a trivial way that’s easy to migrate).

···

On Nov 6, 2017, at 4:33 PM, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I use this on all of my mutable optional properties, when I have to use them. It’s just that little extra bit of code I don’t need to write, and it feels a lot like parameter defaults in use. By surface area, I assume you mean the fact that it’s an implicit behavior people may need to remember? As something like that, this seems like a very small one. As for users knowing about it, I’m guessing it falls into one of those things that people just never explicitly notice but would likely have a huge impact on anyone with lots of mutable optionals. Developers from other languages may also assume this behavior, since it replicates the “nil by default” behavior seen in other languages.
  Ultimately, while I won’t feel this deeply, since I tend to view mutable optionals as poor practice in Swift, it’s a nice little convenience that will likely impact everyone using mutable optionals. If you really want to find out, perhaps run it agains the compatibility suite?

Jon

···

On Nov 6, 2017, at 5:33 PM, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
var x: Int?
}

struct S {
var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

hot take: i use the second one a lot but only because i always forget the
first one exists. So I type the = nil just to “be sure”.

···

On Mon, Nov 6, 2017 at 4:33 PM, Slava Pestov via swift-evolution < swift-evolution@swift.org> wrote:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
  var x: Int?
}

struct S {
  var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!)
always have a default value of ‘nil’. This feature increases the surface
area of the language for no good reason, and I would like to deprecate it
in -swift-version 5 with a short proposal. Does anyone feel strongly about
giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Just a quick question for clarification. What will happen to these? Do we have to provide the default value ourselves?

class ViewController : UIViewController {

@IBOutlet weak var view1: UIView?

@IBOutlet weak var view2: UIView\!

}

···

Am 6. November 2017 um 23:33:51, Slava Pestov via swift-evolution (swift-evolution@swift.org) schrieb:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
var x: Int?
}

struct S {
var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Yeah, I use the first form constantly.

···

On 6 Nov 2017, at 23:33, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
var x: Int?
}

struct S {
var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

On the other side, I'd say requiring explicit initialization to nil
increases the amount of busywork for the programmer for no good reason. I
use it all the time and I would be pretty annoyed if it went away. I would
be pretty shocked if most Swift users don't know that exists.

···

On Mon, Nov 6, 2017 at 2:33 PM, Slava Pestov via swift-evolution < swift-evolution@swift.org> wrote:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
  var x: Int?
}

struct S {
  var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!)
always have a default value of ‘nil’. This feature increases the surface
area of the language for no good reason, and I would like to deprecate it
in -swift-version 5 with a short proposal. Does anyone feel strongly about
giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Functional Programmer, iOS Developer, Surfs Poorly
http://twitter.com/n8gray

1 Like

hot take: i use the second one a lot but only because i always forget the first one exists. So I type the = nil just to “be sure”.

Same here! I just changed a bunch of code since I’d forgotten they were the same

···

On Nov 6, 2017, at 5:29 PM, Kelvin Ma via swift-evolution <swift-evolution@swift.org> wrote:

On Mon, Nov 6, 2017 at 4:33 PM, Slava Pestov via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi all,

Right now, the following two declarations are equivalent:

struct S {
  var x: Int?
}

struct S {
  var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

hot take: i use the second one a lot but only because i always forget the first one exists. So I type the = nil just to “be sure”.

Yeah, that’s one of my arguments against having the feature, along with the simple fact that if the language did not have it already, nobody would be requesting this to be added as a special case for optionals.

However, since I also want to avoid needless source compatibility churn, I’m fine with keeping the feature — it’s not a huge burden to maintain (unlike, say, AnyObject dispatch :slight_smile: )

Slava

···

On Nov 6, 2017, at 4:29 PM, Kelvin Ma <kelvin13ma@gmail.com> wrote:

On Mon, Nov 6, 2017 at 4:33 PM, Slava Pestov via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hi all,

Right now, the following two declarations are equivalent:

struct S {
  var x: Int?
}

struct S {
  var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

I won’t complain a lot if it’s decided to be removed but I would prefer it to stay. I use it constantly.

···

Sent from my iPad

On 6 Nov 2017, at 22:41, Jon Shier via swift-evolution <swift-evolution@swift.org> wrote:

   I use this on all of my mutable optional properties, when I have to use them. It’s just that little extra bit of code I don’t need to write, and it feels a lot like parameter defaults in use. By surface area, I assume you mean the fact that it’s an implicit behavior people may need to remember? As something like that, this seems like a very small one. As for users knowing about it, I’m guessing it falls into one of those things that people just never explicitly notice but would likely have a huge impact on anyone with lots of mutable optionals. Developers from other languages may also assume this behavior, since it replicates the “nil by default” behavior seen in other languages.
   Ultimately, while I won’t feel this deeply, since I tend to view mutable optionals as poor practice in Swift, it’s a nice little convenience that will likely impact everyone using mutable optionals. If you really want to find out, perhaps run it agains the compatibility suite?

Jon

On Nov 6, 2017, at 5:33 PM, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
var x: Int?
}

struct S {
var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Same here, but I wouldn’t care much if it were gone.

Yeah, I use the first form constantly.

···

Am 7. November 2017 um 21:40:56, David Hart via swift-evolution (swift-evolution@swift.org) schrieb:

On 6 Nov 2017, at 23:33, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
var x: Int?
}

struct S {
var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

It sounds like several people rely on this behavior and are actually aware that it exists, so I won’t pursue the issue further.

Thanks for the feedback!

···

On Nov 6, 2017, at 3:07 PM, Alejandro Martinez <alexito4@gmail.com> wrote:

I won’t complain a lot if it’s decided to be removed but I would prefer it to stay. I use it constantly.

Sent from my iPad

On 6 Nov 2017, at 22:41, Jon Shier via swift-evolution <swift-evolution@swift.org> wrote:

  I use this on all of my mutable optional properties, when I have to use them. It’s just that little extra bit of code I don’t need to write, and it feels a lot like parameter defaults in use. By surface area, I assume you mean the fact that it’s an implicit behavior people may need to remember? As something like that, this seems like a very small one. As for users knowing about it, I’m guessing it falls into one of those things that people just never explicitly notice but would likely have a huge impact on anyone with lots of mutable optionals. Developers from other languages may also assume this behavior, since it replicates the “nil by default” behavior seen in other languages.
  Ultimately, while I won’t feel this deeply, since I tend to view mutable optionals as poor practice in Swift, it’s a nice little convenience that will likely impact everyone using mutable optionals. If you really want to find out, perhaps run it agains the compatibility suite?

Jon

On Nov 6, 2017, at 5:33 PM, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
var x: Int?
}

struct S {
var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

I used the existence of the first one in my explanation of explain
optionals. "There is a reasonable default value for an optional type.
'nothing'."

TJ

···

On Mon, Nov 6, 2017 at 6:52 PM, Slava Pestov via swift-evolution < swift-evolution@swift.org> wrote:

On Nov 6, 2017, at 4:29 PM, Kelvin Ma <kelvin13ma@gmail.com> wrote:

hot take: i use the second one a lot but only because i always forget the
first one exists. So I type the = nil just to “be sure”.

Yeah, that’s one of my arguments against having the feature, along with
the simple fact that if the language did not have it already, nobody would
be requesting this to be added as a special case for optionals.

However, since I also want to avoid needless source compatibility churn,
I’m fine with keeping the feature — it’s not a huge burden to maintain
(unlike, say, AnyObject dispatch :slight_smile: )

Slava

On Mon, Nov 6, 2017 at 4:33 PM, Slava Pestov via swift-evolution < > swift-evolution@swift.org> wrote:

Hi all,

Right now, the following two declarations are equivalent:

struct S {
  var x: Int?
}

struct S {
  var x: Int? = nil
}

That is, mutable bindings of sugared optional type (but not Optional<T>!)
always have a default value of ‘nil’. This feature increases the surface
area of the language for no good reason, and I would like to deprecate it
in -swift-version 5 with a short proposal. Does anyone feel strongly about
giving it up? I suspect most Swift users don’t even know it exists.

Slava
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

Not a big deal either way, but I prefer the 2nd (nil) form and therefore
would like to see the 1st form go. It would make Swift more consistent,
consider:

let o: Int? // Looks like nil is assigned.
if someTest {
    o = 1 // Why isn't this an error? (OK I know why - but it looks odd.)
} else {
    o = nil
}

Whilst the above works it is weird because if you are aware that o: Int?
normally assigns nil then the above looks like o, which is a let, is
assigned to twice. If you do the equivalent of the above for a non-optional
it is an error.

  -- Howard.

···

On 8 November 2017 at 07:54, Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

Same here, but I wouldn’t care much if it were gone.

Am 7. November 2017 um 21:40:56, David Hart via swift-evolution (
swift-evolution@swift.org) schrieb:

Yeah, I use the first form constantly.

> On 6 Nov 2017, at 23:33, Slava Pestov via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Hi all,
>
> Right now, the following two declarations are equivalent:
>
> struct S {
> var x: Int?
> }
>
> struct S {
> var x: Int? = nil
> }
>
> That is, mutable bindings of sugared optional type (but not
Optional<T>!) always have a default value of ‘nil’. This feature increases
the surface area of the language for no good reason, and I would like to
deprecate it in -swift-version 5 with a short proposal. Does anyone feel
strongly about giving it up? I suspect most Swift users don’t even know it
exists.
>
> Slava
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

Not a big deal either way, but I prefer the 2nd (nil) form and therefore would like to see the 1st form go. It would make Swift more consistent, consider:

let o: Int? // Looks like nil is assigned.
if someTest {
    o = 1 // Why isn't this an error? (OK I know why - but it looks odd.)
} else {
    o = nil
}

Whilst the above works it is weird because if you are aware that o: Int? normally assigns nil then the above looks like o, which is a let, is assigned to twice. If you do the equivalent of the above for a non-optional it is an error.

The default initialization behavior is specifically not enabled for let bindings. Compare:

let x: Int?
print(x as Any) // error: constant 'x' used before being initialized

var y: Int?
print(y as Any)

So your example is perfectly consistent, because you’re only initializing ‘o’ once (along each control flow path).

Slava

···

On Nov 7, 2017, at 11:22 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:

  -- Howard.

On 8 November 2017 at 07:54, Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Same here, but I wouldn’t care much if it were gone.

Am 7. November 2017 um 21:40:56, David Hart via swift-evolution (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:

Yeah, I use the first form constantly.

> On 6 Nov 2017, at 23:33, Slava Pestov via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> Hi all,
>
> Right now, the following two declarations are equivalent:
>
> struct S {
> var x: Int?
> }
>
> struct S {
> var x: Int? = nil
> }
>
> That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.
>
> Slava
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Although I’m fine with the current behavior I’d go for the explicit init form.
Swift promotes explicit value bindings avoiding surprises which I learnt to like.

In Java private Optional<T> var; field declaration without RHS simply gets inited with a null value and not the expected “none”. Really annoying.

Gábor

···

Sent from my iPhone

On 2017. Nov 8., at 9:06, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

On Nov 7, 2017, at 11:22 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:

Not a big deal either way, but I prefer the 2nd (nil) form and therefore would like to see the 1st form go. It would make Swift more consistent, consider:

let o: Int? // Looks like nil is assigned.
if someTest {
    o = 1 // Why isn't this an error? (OK I know why - but it looks odd.)
} else {
    o = nil
}

Whilst the above works it is weird because if you are aware that o: Int? normally assigns nil then the above looks like o, which is a let, is assigned to twice. If you do the equivalent of the above for a non-optional it is an error.

The default initialization behavior is specifically not enabled for let bindings. Compare:

let x: Int?
print(x as Any) // error: constant 'x' used before being initialized

var y: Int?
print(y as Any)

So your example is perfectly consistent, because you’re only initializing ‘o’ once (along each control flow path).

Slava

  -- Howard.

On 8 November 2017 at 07:54, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
Same here, but I wouldn’t care much if it were gone.

Am 7. November 2017 um 21:40:56, David Hart via swift-evolution (swift-evolution@swift.org) schrieb:

Yeah, I use the first form constantly.

> On 6 Nov 2017, at 23:33, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:
>
> Hi all,
>
> Right now, the following two declarations are equivalent:
>
> struct S {
> var x: Int?
> }
>
> struct S {
> var x: Int? = nil
> }
>
> That is, mutable bindings of sugared optional type (but not Optional<T>!) always have a default value of ‘nil’. This feature increases the surface area of the language for no good reason, and I would like to deprecate it in -swift-version 5 with a short proposal. Does anyone feel strongly about giving it up? I suspect most Swift users don’t even know it exists.
>
> Slava
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution