[swift-evolution] [Draft] Abolish IUO type

James Campbell james at supmenow.com
Fri Mar 18 06:20:32 CDT 2016

One thing I've had bit me is the lack of some sort of confirmation, see
this example.

I have a objective-c method in a library like so:

- (void)observe:(CallbackBlock)block;

The CallbackBlock is a type def-ed block like so:

typedef void (^CallbackBlock)(FDataSnapshot *snapshot);

The parameter in the block gets converted into a IUO, I ended up releasing
an app that crashed due to that IUO being nil.

The code that crashed was something like this

object.observe {

There is no way to tell that the $0 was a IUO. The compiler didn't force me
to confirm in it in some way using a ! and unless I remembered to check the
header I would have a crash.

How would this work under your proposal ?


*James⎥Head Of CEO*

*james at supmenow.com <james at supmenow.com>⎥supmenow.com <http://supmenow.com>*


*Runway East *

*10 Finsbury Square*


* EC2A 1AF *

On Wed, Mar 16, 2016 at 5:03 AM, Chris Willmore via swift-evolution <
swift-evolution at swift.org> wrote:

> Hi, swift-evolution,
> Some colleagues and I have been working on a proposal
> <https://github.com/cwillmor/swift-evolution/blob/master/proposals/0000-abolish-iuo.md> to
> remove the ImplicitlyUnwrappedOptional type from Swift and replace it with
> an IUO decl attribute. Please have a look; I would greatly appreciate any
> comments you have before I push this proposal forward.
> https://github.com/cwillmor/swift-evolution/blob/master/proposals/0000-abolish-iuo.md
> Thanks,
> — Chris Willmore
> Abolish ImplicitlyUnwrappedOptional type
>    - Proposal: SE-NNNN
>    - Author: Chris Willmore <http://github.com/cwillmor>
>    - Status: TBD
>    - Review Manager: TBD
> This proposal seeks to remove the ImplicitlyUnwrappedOptional type from
> the Swift type system and replace it with an IUO attribute on declarations.
> Appending ! to the type of a Swift declaration will give it optional type
> and annotate the declaration with an attribute stating that it (or, in the
> case of a function, the return value of its application) may be implicitly
> unwrapped.
> <https://github.com/cwillmor/swift-evolution/blob/89971a8162eba3aeb238d47772cda295a02cc585/proposals/0000-abolish-iuo.md#motivation>
> Motivation
> The ImplicitlyUnwrappedOptional ("IUO") type is a valuable tool for
> importing Objective-C APIs where the nullability of a parameter or return
> type is unspecified. It also represents a convenient mechanism for working
> through definite initialization problems in initializers. However, IUOs are
> a transitional technology; they represent an easy way to work around
> un-annotated APIs, or the lack of language features that could more
> elegantly handle certain patterns of code. As such, we would like to limit
> their usage moving forward, and introduce more specific language features
> to take their place. Except for a few specific scenarios, optionals are
> always the safer bet, and we’d like to encourage people to use them instead
> of IUOs.
> 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. It also completely abolishes any
> notion of IUOs below the type-checker level of the compiler, which will
> substantially simplify the compiler implementation.
> <https://github.com/cwillmor/swift-evolution/blob/89971a8162eba3aeb238d47772cda295a02cc585/proposals/0000-abolish-iuo.md#proposed-solution>Proposed
> solution
> I propose demoting implicitly unwrapped optionals from being a first-class
> type in the Swift type system to being an attribute on declarations in
> Swift. This attribute will be allowed in the following locations:
>    - property and variable declarations
>    - initializer declarations
>    - function declarations
> Declarations that are marked with the IUO attribute must have optional
> type. A reference to a variable or property with the IUO attribute may be
> implicitly forced (i.e. converted to the underlying type) when being
> type-checked, thus replicating the current behavior of a declaration with
> IUO type. Likewise, the result of a function application or initialization
> where the callee is a reference to a function declaration with the IUO
> attribute may be implicitly forced.
> The appearance of ! at the end of a property or variable type no longer
> indicates that the property or variable has IUO type; rather, it indicates
> that (1) the declaration has optional type, and (2) the declaration has the
> IUO attribute. The appearance of ! at the end of the return type of a
> function indicates that the function has optional return type and the IUO
> attribute. The use of init! in an initializer declaration indicates that
> the initializer is failable and has the IUO attribute.
> Because there is no longer an IUO type, types with nested IUOs are no
> longer allowed. This includes types such as [Int!] and (Int!, Int!).
> The IUO attribute is not inferred from one declaration to another. For
> example, in the following code:
> let x: Int! = 5
> let y = x
> … x and y both have type Int?, not Int!, and y lacks the IUO attribute.
> This rule prevents IUO attributes from spreading via type inference.
> A variable with the IUO attribute may still be converted to a value with
> non-optional type, through either evaluating it in a context which requires
> the non-optional type, explicitly converting it to a non-optional type
> using the as operator, binding it to a variable with explicit optional
> type, or using the force operator (!).
> <https://github.com/cwillmor/swift-evolution/blob/89971a8162eba3aeb238d47772cda295a02cc585/proposals/0000-abolish-iuo.md#examples>
> Examples
> func f() -> Int! { return 3 } // f: () -> Int?, has IUO attribute
> let x1 = f() // succeeds; x1: Int? == 3
> let x2: Int? = f() // succeeds; x2: Int? = .Some(3)
> let x3: Int! = f() // succeeds; x3: Int? = .Some(3), has IUO attribute
> let x4: Int = f() // succeeds; x4: Int = 3
> let a1 = [f()] // succeeds; a: [Int?] = [.Some(3)]
> let a2: [Int!] = [f()] // illegal, nested IUO type
> let a3: [Int] = [f()] // succeeds; a: [Int] = [3]
> func g() -> Int! { return nil } // f: () -> Int?, has IUO attribute
> let y1 = g() // succeeds; y1: Int? = .None
> let y2: Int? = g() // succeeds; y2: Int? = .None
> let y3: Int! = g() // succeeds; y3: Int? = .None, has IUO attribute
> let y4: Int = g() // traps
> let b1 = [g()] // succeeds; b: [Int?] = [.None]
> let b2: [Int!] = [g()] // illegal, nested IUO type
> let b3: [Int] = [g()] // traps
> func p<T>(x: T) { print(x) }
> p(f()) // prints "Optional(3)"; p is instantiated with T = Int?
> if let x5 = f() {
>   // executes, with x4: Int = 3
> }
> if let y5 = g() {
>   // does not execute
> }
> <https://github.com/cwillmor/swift-evolution/blob/89971a8162eba3aeb238d47772cda295a02cc585/proposals/0000-abolish-iuo.md#impact-on-existing-code>Impact
> on existing code
> Variable bindings which previously had inferred type T! from their
> binding on the right-hand side will now have type T?. The compiler will
> emit an error at sites where those bound variables are used in a context
> that demands a non-optional type and suggest that the value be forced with
> the ! operator.
> Explicitly written nested IUO types (like [Int!]) will have to be
> rewritten to use the corresponding optional type ([Int?]) or non-optional
> type ([Int]) depending on what's more appropriate for the context.
> However, most declarations with non-nested IUO type will continue to work
> as they did before.
> It will still be possible to declare IUO properties, so the following
> deferred initialization pattern will still be possible:
> struct S {
>   var x: Int!
>   init() {}
>   func initLater(x someX: Int) { x = someX }
> }
> <https://github.com/cwillmor/swift-evolution/blob/89971a8162eba3aeb238d47772cda295a02cc585/proposals/0000-abolish-iuo.md#future-directions>Future
> directions
> Because this proposal changes the IUO-ness of a declaration from being
> part of its type to being an attribute of the declaration, it might make
> sense to changes the syntactic representation of the attribute to match,
> e.g. by creating a new @implicitly_unwrapped attribute on declarations:
> let x3: Int! = f() // !-based syntax
> @implicitly_unwrapped let x3: Int? = f() // attribute-based syntax
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160318/28b51ede/attachment.html>

More information about the swift-evolution mailing list