> 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

Reply via email to