<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 24, 2016, at 6:27 PM, Greg Parker &lt;<a href="mailto:gparker@apple.com" class="">gparker@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Aug 23, 2016, at 3:36 PM, Douglas Gregor via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class="">Proposed solution</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">When an&nbsp;<code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Optional&lt;T&gt;</code>&nbsp;value is bridged to an Objective-C object, if it contains&nbsp;<code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">some</code>&nbsp;value, that value should be bridged; otherwise,&nbsp;<code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">NSNull</code>&nbsp;or another sentinel object should be used.</p></div></div></blockquote>I don't think I like this.</div><div class=""><br class=""></div><div class="">Let me verify my understanding. If I have this:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; // imported from ObjC</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; func f(with object: Any)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; let s: String? = nil</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; f(s)</font></div><div class=""><br class=""></div><div class="">then at runtime it will call&nbsp;</div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; f([NSNull null])</font></div><div class="">?</div><div class=""><br class=""></div><div class="">The problem is that NSNull is in fact rare in Cocoa. They are used in the Foundation containers and almost nowhere else. Passing NSNull into almost any API is going to do something confusing at runtime. If you're lucky you get a prompt error "-[NSNull something]: unrecognized selector". If you're not lucky you'll get that error somewhere much later, or something even less obviously related to NSNull and your call site. That sounds like the wrong outcome for developers who are confused or careless or unaware of an optional.</div></div></div></blockquote><br class=""></div><div>I think there’s some confusion about what’s already in place due to&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0116-id-as-any.md" class="">SE-0116</a>&nbsp;vs. what’s being proposed here. Specifically, your example:</div><div><br class=""></div><div><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><font face="Menlo" class="">&nbsp; &nbsp; // imported from ObjC</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; func f(with object: Any)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; let s: String? = nil</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; f(with:s)</font></div></div></blockquote></div><div><br class=""></div><div>Is accepted as part of SE-0116, because any Swift type can be placed in an Any, and anything can be bridged to Objective-C. Nearly all of the concerns in this thread are about this aspect of the already-accepted-and-implemented SE-0116: that an optional can get passed through to an Objective-C ‘id’ without being explicitly unwrapped. That behavior exists, and the type of the object seen in Objective-C is an opaque Swift wrapper type. I’d thought we were going to get some warnings when putting an optional into an Any that would end up going into Objective-C, but I don’t see the warning: maybe Joe can weigh in as to why we didn’t do that.&nbsp;</div><div><br class=""></div><div>*This* proposal is to make the object seen from Objective-C [NSNull null], so at least it’s predictable/detectable on the Objective-C side.</div><div><br class=""></div><div>Now, for the related example:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>let s2: String? = “hello”</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>f(with: s2)</div><div><br class=""></div><div>Objective-C will see an NSString (well, Swift’s private subclass of NSString), rather than an opaque Swift wrapper type.</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div><br class=""></div><br class=""></body></html>