> On Mar 18, 2016, at 4:20 AM, James Campbell <[email protected]> wrote: > > 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 { > $0.doSomething() > } > > 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 ?
This is a great question. I think it would make the most sense to import the CallbackBlock type as (FDataSnapshot?) -> (), since there’s no decl to hang the IUO attribute onto. Then $0 ends up with type FDataSnapshot? (i.e. Optional<FDataSnapshot>), and the compiler would not allow you to simply call doSomething() on $0 without forcing it first. — Chris Willmore > > ___________________________________ > > James⎥Head Of CEO > > [email protected] <mailto:[email protected]>⎥supmenow.com > <http://supmenow.com/> > Sup > > Runway East > > > 10 Finsbury Square > > London > > > EC2A 1AF > > > On Wed, Mar 16, 2016 at 5:03 AM, Chris Willmore via swift-evolution > <[email protected] <mailto:[email protected]>> 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 > > <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 > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
