Thanks for the thoughtful response, Chris. Comments inline. I’ve updated the draft linked below to reflect your feedback.
> On Mar 16, 2016, at 5:01 PM, Chris Lattner <[email protected]> wrote: > > On Mar 15, 2016, at 10:03 PM, 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> > You already know this, but I am +100 on this proposal. We definitely need to > “nerf” IUO, to get to a more predictable and robust model. > > Some minor comments on the writing below. The most significant one is that I > think that describing this in terms of an IUO attribute (which is an internal > implementation detail) makes the proposal more confusing than necessary for > the non-compiler hackers. :-) Well, IUO is no longer a type, so what do we call it? I agree that it’s weird to call it an attribute when there’s no way to spell it explicitly as such, but I’m at a loss for alternatives. Maybe we could just say that such a declaration is implicitly unwrapped (forced? unwrappable? forceable?), or declares an implicitly unwrapped property/function/variable. Anyway, I’ve changed “declaration with the IUO attribute” to “IUO declaration” in all places but the first occurrence in my revision. >> >> >> <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 > + Function decls includes the result type as well as the parameter decls, but > not a varargs element type. > + Subscripts. Good call, added. I added “parameter declarations” as a line item rather than qualify the function-declarations line (and repeat the qualification for initializers, methods, subscripts). >> Declarations that are marked with the IUO attribute must have optional type. >> > Is the IUO attribute actually user exposed in any way, or is it an internal > compiler detail? I would expect us to continue to use and prefer (e.g. in > the ASTPrinter) the T! syntax. Re the comment above, should this be rewritten as “Implicitly unwrapped declarations 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. >> > For clarity in the wording, I’d suggest something along the lines of: > > "A reference to a variable or property with the IUO attribute prefers to bind > to an optional, but may also be implicitly forced …” Yep, makes sense; added. > >> 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. >> > This again is talking about the compiler implementation details. Possible resolution: “… (2) the declaration may be implicitly unwrapped”? Likewise “… the return value of the function may be implicitly unwrapped". > >> 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. >> > I think that this statement will draw confusion in review, because “x” has > IUO behavior. Perhaps you can talk about it in terms of type propagation and > describe the behavior along the lines of: > > if the expression can be successfully type checked with the declaration > producing a strong optional, it does. However, the type checker will fall > back to trying to fall back to forcing the optional - if that succeeds it > will. The end result of this is that the result of any rvalue that refers to > something declared as an IUO will either have T or T? type. This means that > in: > > let x: Int! = 5 > let y = x > let z = x+0 > > “x” is declared as an IUO, but because the initializer for y type checks > correctly as an optional, y will be bound as type "Int?”. Since the > initializer for z does not type check with x declared as an optional, the > compiler forces the IUO and type checks the initializer as an Int. > > This model is more predictable, because IUOs are forced much more locally to > where they are introduced into code, they do not propagate unpredictably > through code. Any unpredictable propagation of an unknownable-null value is > instead propagates as a strong optional, which is the safe default. Thanks for the detailed feedback here. I’ve rewritten this section. > > >> >> <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) > .some and .none are lower case these days :-) So they are! Fixed. >> >> <https://github.com/cwillmor/swift-evolution/blob/89971a8162eba3aeb238d47772cda295a02cc585/proposals/0000-abolish-iuo.md#impact-on-existing-code>Impact >> on existing code >> > I would add an intro paragraph/sentence saying that we do expect this to be a > source breaking change, and thus it makes sense to do in Swift 3. We > consider this to be acceptable because IUOs coming in through imported ObjC/C > modules naturally “shimmer” in IUO’ness as nullability gets audited. > >> 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. >> > > Overall, looks great, thank you for writing this up! Thank you! — Chris W.
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
