[Review] SE-0054: Abolish ImplicitlyUnwrappedOptional type


(Chris Lattner) #1

Hello Swift community,

The review of "Abolish ImplicitlyUnwrappedOptional type" begins now and runs through March 30th. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at:
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  * What is your evaluation of the proposal?
  * Is the problem being addressed significant enough to warrant a change to Swift?
  * Does this proposal fit well with the feel and direction of Swift?
  * If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager


(Juan Ignacio Laube) #2

* What is your evaluation of the proposal?
+1. I agree that ImplicitlyUnwrappedOptional are a transition technology. And therefore, its usage should be limited.

* Is the problem being addressed significant enough to warrant a change to Swift?
Yes.

* Does this proposal fit well with the feel and direction of Swift?
Yes. And I agree this should be shipped with Swift 3.

* If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
I think Rust has this kind of null safety already using an Optional type to indicate the absence of a value.

* How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
Read the review and followed the discussion in swift-evolution.

···

On Mar 25, 2016, at 12:24 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of "Abolish ImplicitlyUnwrappedOptional type" begins now and runs through March 30th. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at:
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  * What is your evaluation of the proposal?
  * Is the problem being addressed significant enough to warrant a change to Swift?
  * Does this proposal fit well with the feel and direction of Swift?
  * If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Chéyo Jiménez) #3

   * What is your evaluation of the proposal?

This is a great idea. I actually feel that I understand IUO much better in this proposal than in the previous model. I do have a question.

let x: Int! = 5
let y = x

let a = x ?? 1 // would this still work?
Or would it auto unwrapping always? meaning when .some `a = 5` or crash when .none?
I am assuming that x is `Int?` that autounwraps. Just curious if autounwraps only happen on assignment like in `y = x`

   * Is the problem being addressed significant enough to warrant a change to Swift?

I believe so, it makes IUO feel more like an automatic behavior on regular optionals.

   * Does this proposal fit well with the feel and direction of Swift?

Yes embracing change while still supporting portable code.

   * If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I've only used this with swift.

   * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read the proposal and followed tread


(Russ Bishop) #4

+1 on this proposal from me. It seems like a good step on the way to removing IUOs entirely.

Russ

···

On Mar 25, 2016, at 8:24 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of "Abolish ImplicitlyUnwrappedOptional type" begins now and runs through March 30th. The proposal is available here:

   https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at:
   https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

   * What is your evaluation of the proposal?
   * Is the problem being addressed significant enough to warrant a change to Swift?
   * Does this proposal fit well with the feel and direction of Swift?
   * If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
   * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

   https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Brent Royal-Gordon) #5

  * What is your evaluation of the proposal?

I am very much in favor overall, but I do have some minor quibbles.

Firstly, the list of places where you can use autounwrapping is kind of vague:

  • property and variable declarations
  • initializer declarations
  • function and method declarations
  • subscript declarations
  • parameter declarations (with the exception of vararg parameters)

I assume that the "function and method declarations" and "subscript declarations" entries mean that you can mark their return values as autounwrapped. The separate "parameter declarations" entry means you can also mark initializer, function, method, and subscript parameters as autounwrapped. Is that correct, or do you mean something else?

If so, is the presence or absence of autounwrapping a part of the function's signature? Do closures derived from that function keep the same autounwrapping behavior? Can a closure be explicitly defined to have autounwrapped parameters or return values?

And if so, why aren't you allowed to make a `typealias` for a closure type which has autounwrapped properties or return values? I understand the rule against having a plain type in a `typealias`; many uses won't actually be able to apply the autounwrapping. But the same won't be true for closures.

Secondly, I continue to believe that the notional @_autounwrapped attribute should be an actual, utterable @autounwrapped attribute, for a couple of reasons.

The first reason is for teaching. (I don't do any formal teaching, but I'm sort of the Swift expert in my local circle of programmers, and frequently give demos and explain things to people.) Complicated sugar benefits from having a simpler, clearer desugared form; it makes the various parts of the sugar's semantics much easier to explain. As an example, consider closure syntax. I never use the fully specified syntax for the closure signature before the `in` keyword *except* when teaching. In teaching contexts, though, it's really useful to be able to start with the full syntax and then strip elements of it away to demonstrate how Swift infers things.

Similarly, I think this feature will benefit immensely from allowing you to strip a `T!` declaration down into more atomic parts. The proposal itself itself benefited immensely from giving the semantic the name `@_autounwrapped`; every book, tutorial, and demo on Swift 3+ which takes on the `T!` syntax will similarly benefit from having a name for the thing. Particularly, I think it's valuable to be able to write both the sugared and desugared forms as executable playground code so users can see that they're equivalent.

The second reason I think `@autounwrapped` should be utterable is that I keep noticing places where you don't have an opportunity to change a regular optional to an autounwrapped one. I already discussed this case:

  @autounwrapped var y = x

But typealiases are another one:

  typealias Delegate = FooDelegate?
  @autounwrapped var delegate: Delegate

Admittedly, neither of these is extremely compelling, but we will only find more, and I worry that some of them might be more serious.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. ImplicitlyUnwrappedOptional has been a problem from the start. The autounwrapped approach is tremendously more rational.

  * Does this proposal fit well with the feel and direction of Swift?

Yes. Swift usually tries to reduce and contain magic; autounwrapped optionals fit those goals a lot better.

  * If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

N/A.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read the proposal, participated pretty heavily in previous discussions.

···

--
Brent Royal-Gordon
Architechies


(Joseph Lord) #6

As I don't use IUO optionals I'm really fairly neutral on the proposal. I just wanted to mention with the powerful tools we have for dealing with optionals (optional, chaining, nil-coalescing, map, flatmap, guard, and let - thanks Chris and team) it really would be quite feasible to do away with IUOs completely. I don't think the community is ready for that yet so I'm not proposing that course of action at this time but such a proposal wouldn't get a universally hostile response.

Even force unwrap is something that I only do test code since flatmap was added to the Standard Library (I used to have my own implementation of flatmap with a force unwrap after a filter which was the only production use I've put force unwrap to).

Joseph

···

On 25/03/2016 15:24, Chris Lattner via swift-evolution wrote:

Hello Swift community,

The review of "Abolish ImplicitlyUnwrappedOptional type" begins now and runs through March 30th. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md


(Michel Fortin) #7

* What is your evaluation of the proposal?

I don't like that proposal as it stands currently.

By the way, I don't use any IUO in my code, except sometime for @IBOutlets. I do encounter them sometime with external APIs, but the way they work in Swift 2 isn't causing me any problem. They are also very easy to reason about being types like regular optionals using a very similar syntax.

* Is the problem being addressed significant enough to warrant a change to Swift?

It's hard to form a good opinion on the problem when there is no description of the problem.

The Motivation part of the proposal is basically a statement of intent:

• IUOs are a transitional technology
• we would like to limit their usage moving forward

Swift is expanding to Linux which has many unannotated APIs; so to me it seems the "transition" is still in progress, and will always be.

The same Motivation part says that IUOs are a valuable tool for importing external APIs and they are convenient in other places. There is not the slightest explanation of when or why they are inconvenient. There is surprisingly no mention of type propagation.

* Does this proposal fit well with the feel and direction of Swift?

I don't like the syntax. In the current Swift, `T!` being the implicitly-unwrapped variant of type `T?` is something that is easy to understand. They look similar and have similar propagation behaviors since the two are types, so they are predictable.

This proposal proposes to change it to a declaration attribute while keeping the same syntax. The resulting concept is a hybrid declaration attribute/type modifier that changes the type from `T` to `T?` and allows implicit unwrap. What you actually see when reading the code is a pseudo-IUO `T!` type that isn't really a type and transform to `T?` when it propagates. I find it a bit strange and unsettling: if it's not a type, it shouldn't look like one. And if the type is a regular optional, that should be the type visible in the declaration. Otherwise it's confusing.

So I can't see a justification for replacing IUOs with this hard to describe part-type/part-attribute thing. I'm pretty sure we'd just be trading one problem (unwanted IUO propagation) for another (hard to grasp semantics).

- - -

On a more general note, it seems to me that if the problem to solve is the silent propagation of IUOs, the compiler could simply require the propagation to be explicit by forcing the user to declare the type of every IUO variable:

  let x: Int! = nil
  let y = x // error: must explicitly declare type Int!
  let z: Int! = x // ok

And that could work for generics too:

  let a = Array(x) // error: must explicitly declare type [Int!]
  let b: [Int!] = Array(x) // ok

* If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

N/A

* How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I read the proposal and some mails on the list that lead to that proposal.

···

--
Michel Fortin
https://michelf.ca


(James Campbell) #8

* What is your evaluation of the proposal?
I think this is a positive step in the right direction but I think there still needs to be more amendments. So a +1 if address the issues I'm about to outline.
Anything not annotated should be imported as an optional not a IUO, this makes it safer to handle the nil case with legacy code.
This is also truer to the intent of the original objective c code.
The proposal so far agrees with this, however there is one part I think could make clearer.
This:
Let x: Int! = 5Let y = x
It's not clear to me that y would be converted to an optional or that it would crash if it couldn't be type converted. This is a huge departure from the existing swift.
I think it would be better to have what I call Optional Type Confermence.
If I want y to be a Int! I can refer to x with a ! :
Let x:Int! = 5Let y = x!
That way if x is nil the app will trap and this provides a path for existing code to still use this behaviour plus it's now obvious that x will be treated like an unwrapped optional.
If you wanted x to be treated like an optional you would use ?
Let x: Int! = 5Let y = x?
This would make the behaviour the proposal is proposing much clearer. * Is the problem being addressed significant enough to warrant a change to Swift?Although the proposal doesn't outline a problem, I do believe the optional system in swift today isn't safe enough. Indeed I released an app that crashed due to swift importing an unannotated piece of objective c code that wasn't clear about how it was an IUO and crashed.Anything that improves this visibility of IUOs and reduces the need of them I am for.
  * Does this proposal fit well with the feel and direction of Swift?This fits with Swift 3s simplification of the APIs * If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?I don't have any experience in other languages. * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

In depth study.

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

···

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


(Bernd Ohr) #9

* What is your evaluation of the proposal?

I don’t like the proposal.

* Is the problem being addressed significant enough to warrant a change to Swift?

I don't agree that IUOs are a transitional technology as long as there is an import of C libraries.

The only problem I see that IUO’s are being used where it is not necessary, either out of ignorance or convenience.

My counter proposal: IUO’s are only allowed (in pure Swift files) with private scope (filePrivate) and not with internal or public scope! In this way the uncontrolled spread of IUO’s can be most easily prevented.

An additional restriction could be that IUO’s are only allowed in files that import C or ObjC libraries.

* Does this proposal fit well with the feel and direction of Swift?

No, because it makes the use of IUO’s much harder (IMHO) where it is really necessary.

* If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

N/A

* How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I read the proposal and had a look at some of my code that uses IUO’s


(Patrick Gili) #10

  * What is your evaluation of the proposal?

The IUO is not a transitional technology, as it is essential to bridge from languages from which Swift evolved, such as C and Objective-C. The proposal doesn't give much consideration to this application of IUOs, and hence, I cannot support the proposal in its current state.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Grant it, the use of IUO outside of bridging is strange and probably a poor practice. However, there seems to exist a requirement and this proposal would make satisfying this requirement more difficult.

  * Does this proposal fit well with the feel and direction of Swift?

No.

  * If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Not applicable.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

In-depth study.


(David Sweeris) #11

I’m pretty sure I only use them with `@IBOutlet` vars.

One of the alternatives list is:
• Remove IUOs completely. Untenable due to the prevalence of deferred initialization and unannotated Objective-C API in today's Swift ecosystem.

What about leaving IUOs in the compiler, but disallowing them unless the code is marked @objc (and treating them as `T?` in code that isn’t)? The stated motivation is "This proposal seeks to limit the adoption of IUOs to places where they are actually required, and put the Swift language on the path to removing implicitly unwrapped optionals from the system entirely when other technologies render them unnecessary.”… If they’re only intended to be used with C/Obj-C code, seems like that’s something that’d be possible for the compiler to enforce.

Having typed this all out, I’m starting to suspect it might be more complicated than what we have now… Hmm… I’ll hit send anyway, in case I’m wrong.

- Dave Sweeris

···

On Mar 25, 2016, at 3:10 PM, Joseph Lord via swift-evolution <swift-evolution@swift.org> wrote:

On 25/03/2016 15:24, Chris Lattner via swift-evolution wrote:

Hello Swift community,

The review of "Abolish ImplicitlyUnwrappedOptional type" begins now and runs through March 30th. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md

As I don't use IUO optionals I'm really fairly neutral on the proposal. I just wanted to mention with the powerful tools we have for dealing with optionals (optional, chaining, nil-coalescing, map, flatmap, guard, and let - thanks Chris and team) it really would be quite feasible to do away with IUOs completely. I don't think the community is ready for that yet so I'm not proposing that course of action at this time but such a proposal wouldn't get a universally hostile response.

Even force unwrap is something that I only do test code since flatmap was added to the Standard Library (I used to have my own implementation of flatmap with a force unwrap after a filter which was the only production use I've put force unwrap to).

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


(Brent Royal-Gordon) #12

I do have a question.

let x: Int! = 5
let y = x

let a = x ?? 1 // would this still work?
Or would it auto unwrapping always? meaning when .some `a = 5` or crash when .none?
I am assuming that x is `Int?` that autounwraps. Just curious if autounwraps only happen on assignment like in `y = x`

I believe that, in this example, `y` is of type `Int?`, that is, a non-autounwrapped optional. An autounwrapped optional is only unwrapped if Swift cannot make the code type-check without unwrapping it.

···

--
Brent Royal-Gordon
Architechies


(Chéyo Jiménez) #13

Ah got it. I missed that part. [1]

I do have a question.

let x: Int! = 5
let y = x

let a = x ?? 1 // would this still work?

This should work then. I guess I never thought about safely “unwrapping" an IUO in swift2 but it works.

Thanks!

Or would it auto unwrapping always? meaning when .some `a = 5` or crash when .none?
I am assuming that x is `Int?` that autounwraps. Just curious if autounwraps only happen on assignment like in `y = x`

I believe that, in this example, `y` is of type `Int?`, that is, a non-autounwrapped optional. An autounwrapped optional is only unwrapped if Swift cannot make the code type-check without unwrapping it.

--
Brent Royal-Gordon
Architechies

[1] “x is declared as an IUO, but because the initializer for y type checks correctly as an optional, y will be bound as typeInt?. However, the initializer for z does not type check with x declared as an optional (there's no overload of + that takes an optional), so the compiler forces the optional and type checks the initializer as Int."

···

On Mar 25, 2016, at 4:16 PM, Brent Royal-Gordon <brent@architechies.com> wrote: