<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="section" id="make-pointer-nullability-explicit-using-optional"><h3 style="margin-top: 30px;" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class="" style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-weight: normal;">To help keep proposals moving forward, the Swift core team has set aside some time specifically for design discussions of&nbsp;upcoming proposals. &nbsp;Below are some rough notes from the yesterday's discussion.</div><div class="" style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-weight: normal;"><br class=""></div><div class="" style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-weight: normal;">(This week, I want to point out that my notes for PR&nbsp;219, the first discussion topic, are especially rough.)</div><div class="" style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-weight: normal;"><br class=""></div><div class="" style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-weight: normal;">These are&nbsp;<i class="">informal</i>&nbsp;comments, intended to guide the proposals in directions that draw constructive feedback. You are welcome to ignore the feedback, agree with it, or disagree with it. &nbsp;As always, the formal decision doesn't happen until after the review period ends.</div><div class="" style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-weight: normal;"><br class=""></div><div class="" style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 14px; font-weight: normal;"><br class=""></div><div style="color: rgb(12, 55, 98); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; font-size: 1.1em; font-weight: normal;" class=""><br class=""></div></div></div></div></div></h3><h3 style="color: rgb(12, 55, 98); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; font-size: 1.1em; font-weight: normal; margin-top: 30px;" class="">Make pointer nullability explicit using Optional<a class="headerlink" href="file:///Users/alexmartini/DevPubs%20Git%20Repositories/Swift%20Language%20Review/_build/html/LR_MeetingNotes/2016-03-23.html#make-pointer-nullability-explicit-using-optional" title="Permalink to this headline" style="visibility: hidden; font-weight: bold; text-decoration: none; color: rgb(167, 206, 56); padding-left: 5px;"></a></h3><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class=""><a class="external reference" href="https://github.com/apple/swift-evolution/pull/219" style="font-weight: bold; text-decoration: none; color: rgb(137, 38, 1);">https://github.com/apple/swift-evolution/pull/219</a></p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">Biggest open issue is what to do with&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">UnsafeBufferPointer</span></tt>&nbsp;which has a base address and a count of the number of elements at that address. The most common use is to do fast things with an array. The problem is when you have an empty array.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">We have a statically initialized empty array, so this doesn’t apply to array. But slices and Cocoa arrays can do it.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">Half of the use cases are subscripting off of the buffer, so they don’t actually use the base address. They can’t actually subscript an empty array, but it’s not a syntax error — the loop is run zero times, so it doesn’t matter. The other half pass the pointers down to a C API that takes an address and count.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">Someone might expect that the base address doesn’t change when something is initialized.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">We can’t easily use the zero pointer because SIL already uses it for&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">nil</span></tt>. But there are issues with using the same representation as C to avoid bridging costs.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">We’re mapping two things in C onto one thing in Swift. In C, the buffer pointer would be&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">__nullable</span>&nbsp;<span class="pre">long</span>&nbsp;<span class="pre">*</span></tt>&nbsp;and the length is&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">ulong</span></tt>.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">Given everything else in the system, it’s more like pointer. We didn’t call it a buffer because that tends to imply ownership.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">Sketching out the state space:</p><table border="1" class="docutils" style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; border: 0px; border-collapse: collapse; font-size: 14px;"><colgroup class=""><col width="30%" class=""><col width="26%" class=""><col width="26%" class=""><col width="17%" class=""></colgroup><tbody valign="top" class=""><tr class="row-odd"><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">Pointer</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">Length</td><td colspan="2" style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">Static type</td></tr><tr class="row-even"><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">null</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">0</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">UBP?</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">&nbsp;</td></tr><tr class="row-odd"><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">valid</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">&gt;= 0</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">UBP</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">&nbsp;</td></tr><tr class="row-even"><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">valid</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">&lt; 0</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">X</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">&nbsp;</td></tr><tr class="row-odd"><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">vull</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">!= 0</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">???</td><td style="vertical-align: top; padding: 1px 8px 1px 5px; border-width: 0px 0px 1px; border-bottom-style: solid; border-bottom-color: rgb(170, 170, 170);" class="">&nbsp;</td></tr></tbody></table><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">This issue would go away if we got rid of the base address on&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">UnsafeBufferPointer</span></tt>, but that would get rid of a number of valid C operations like calling&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">memcopy</span></tt>.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">It seems like&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">withUnsafeBufferPointer</span></tt>&nbsp;should never produce nil. With that in mind, why should&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">UnsafeBufferPointer</span></tt>&nbsp;need to?</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">We do need a properly-aligned “valid” invalid pointer. LLVM makes assumptions about things being aligned.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">Dominant feedback on the list has been for people want something that round trips cleanly. Making the base address non-optional adds overhead and removes the ability to round trip.</p><p style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; text-align: justify;" class="">It’s unfortunate that we don’t have a way to represent in the type system a buffer pointer that isn’t nullable, from within&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">withUnsafeBufferPointer</span></tt>&nbsp;which wouldn’t even call its closure if the buffer has a null base address.</p></div><div class="section" id="allow-swift-types-to-provide-custom-objective-c-representations" style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;"><h3 style="font-size: 1.1em; font-weight: normal; color: rgb(12, 55, 98); margin-top: 30px;" class="">Allow Swift types to provide custom Objective-C representations<a class="headerlink" href="file:///Users/alexmartini/DevPubs%20Git%20Repositories/Swift%20Language%20Review/_build/html/LR_MeetingNotes/2016-03-23.html#allow-swift-types-to-provide-custom-objective-c-representations" title="Permalink to this headline" style="visibility: hidden; font-weight: bold; text-decoration: none; color: rgb(167, 206, 56); padding-left: 5px;"></a></h3><p style="text-align: justify;" class=""><a class="external reference" href="https://github.com/apple/swift-evolution/pull/198" style="font-weight: bold; text-decoration: none; color: rgb(137, 38, 1);">https://github.com/apple/swift-evolution/pull/198</a></p><p style="text-align: justify;" class="">The associated type could be&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">AnyObject</span></tt>&nbsp;rather than&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">NSObject</span></tt>. The use case for a non-subclass of&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">NSObject</span></tt>&nbsp;is very narrow, but it’s not a needed restriction.</p><p style="text-align: justify;" class="">The&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">unconditionalyBridgeFromObjectiveC</span></tt>&nbsp;function can probably go away. Calling initializers from the downcasting infrastructure is horrible. If we need a function, they</p><p style="text-align: justify;" class="">This doesn’t break the ability of the optimizer to reason about what a dynamic cast can do. We require that the bridgeable conformance must be in the same module as where the type is defined, and we have a white list of things that don’t follow that. Ok... but do we&nbsp;<em class="">want</em>&nbsp;people to expand casting this way? If we say no, we should take it away from array and string and dictionary too.</p><p style="text-align: justify;" class="">You shouldn’t need implicit conversions — the use case is very narrow, and we would rather have things use explicit conversions. The APIs come in with the right type; the implementation of the bridged type has to do conversion, but its clients don’t have to see that. From the Swift point of view, there won’t be any APIs that take the reference type.</p><p style="text-align: justify;" class="">Implicit conversions. In this proposals, you don’t get implicit conversions. Have a separate discussion about whether we can get rid of the four types that have implicit conversion. We see the existing ones as deeply problematic.</p><p style="text-align: justify;" class="">Dynamic casts. For example,&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">AnyObject</span></tt>&nbsp;to a bridged value type. The whole reason for the dynamic cast infrastructure is to make the reference types irrelevant. Should this be using cast syntax or should we have a different type of function? It’s hard to describe what&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">as</span></tt>&nbsp;does. It’s magic because you are casting&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">AnyObject</span></tt>&nbsp;to a struct — calling it&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">AnyObject</span></tt>&nbsp;doesn’t make a lot of sense.</p><p style="text-align: justify;" class="">If we have reference counted existentials, we could merge&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">Any</span></tt>&nbsp;and&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">AnyObject</span></tt>.</p><p style="text-align: justify;" class="">Resilience concern: you can&nbsp;<em class="">not</em>&nbsp;add this protocol after the type has been published.</p></div><div class="section" id="se-0054-abolish-implicitlyunwrappedoptional-type" style="color: rgb(51, 51, 51); font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;"><h3 style="font-size: 1.1em; font-weight: normal; color: rgb(12, 55, 98); margin-top: 30px;" class="">SE-0054: Abolish ImplicitlyUnwrappedOptional type<a class="headerlink" href="file:///Users/alexmartini/DevPubs%20Git%20Repositories/Swift%20Language%20Review/_build/html/LR_MeetingNotes/2016-03-23.html#se-0054-abolish-implicitlyunwrappedoptional-type" title="Permalink to this headline" style="visibility: hidden; font-weight: bold; text-decoration: none; color: rgb(167, 206, 56); padding-left: 5px;"></a></h3><p style="text-align: justify;" class=""><a class="external reference" href="https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md" style="font-weight: bold; text-decoration: none; color: rgb(137, 38, 1);">https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md</a></p><p style="text-align: justify;" class="">IUO as a type is bad; it should become conceptually a decl attribute instead. If we import things that can be nil, their formal type is&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">Optional</span></tt>&nbsp;but we can add an attribute that says when you form a rvalue to that thing, you get implicit unwrapping. The typechecker inserts a diamond that lets you convert it to&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">T?</span></tt>&nbsp;or&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">T</span></tt>. Meaning&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">T!</span></tt>&nbsp;never enters the type system — although it does still appear in user-facing decl descriptions.</p><p style="text-align: justify;" class="">For example:</p><div class="highlight-python"><pre style="overflow-x: auto; overflow-y: hidden; border: thin dotted rgb(12, 55, 98); margin-top: 0px; margin-bottom: 12px; padding: 0.8em; background-color: rgb(240, 240, 240);" class="">let y = P       // y is of type T?
let y: T! = P   // y is of type T!
let x = [P]     // x is of type [T?]</pre></div><p style="text-align: justify;" class="">One issue is that we don’t have a good way to mark a function that takes a block pointer, when that block has not been audited.</p><div class="highlight-python"><pre style="overflow-x: auto; overflow-y: hidden; border: thin dotted rgb(12, 55, 98); margin-top: 0px; margin-bottom: 12px; padding: 0.8em; background-color: rgb(240, 240, 240);" class="">void foo(C *(*fp)(C* x)) {}
func foo (fp: ((C?) -&gt; C?)!) {}
func foo (@IUO fp: (C?) -&gt; C?) {}</pre></div><p style="text-align: justify;" class="">That is a regression from our current behavior. It would have to be a type attribute because they can chain. This will show up in places where you return (and then call) a block.</p><p style="text-align: justify;" class="">For example, you can no longer express the type&nbsp;<tt class="literal docutils" style="background-color: rgb(226, 226, 226); font-size: 1em;"><span class="pre">let</span>&nbsp;<span class="pre">y:</span>&nbsp;<span class="pre">(T?,</span>&nbsp;<span class="pre">U!)</span></tt>.</p><p style="text-align: justify;" class="">We don’t need to have a diamond for currying, only for rvalue access and application.</p><div class="highlight-python"><pre style="overflow-x: auto; overflow-y: hidden; border: thin dotted rgb(12, 55, 98); margin-top: 0px; margin-bottom: 12px; padding: 0.8em; background-color: rgb(240, 240, 240);" class="">x.foo()         // T!
Type.foo(x)()   // T? return type</pre></div><p style="text-align: justify;" class="">A source breaking change here is that if extract something into an intermediate variable could change type in a very important way. That’s already somewhat true because of overload resolution, but this makes it much more visible.</p><p style="text-align: justify;" class="">Does this gloss over the audit problem? We’ve gotten most of the really important stuff audited, but there are lots of unaudited things such as most of the SDK on Linux. This means we don’t propagate the IUO stuff up, meaning we end up with more explicit forces in code when you are using unaudited API.</p><p style="text-align: justify;" class="">Deferred initialization is still a good argument for why we need the feature. This approach locks down propagation and makes IUO more predictable: if the expression can typecheck as optional it will, otherwise it will force.</p></div></body></html>