<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="" applecontenteditable="true"><div class="">The feature in this case I would claim is independent of the adopters. Personally I think this would be a useful feature to allow for better exposition into swift but also more robust objective-c APIs.</div><div class=""><br class=""></div><div class="">Something to consider here is that not all NSUIntegers can be NSNotFound, sometimes the return value is 0. It would be interesting to consider that _Nullable would be parameterized via a constant expression. This is a straw man refinement here (the exact spelling would be something we would have to audit the way it is implemented and likely use macros to compose the right nullability concepts)</div><div class=""><br class=""></div><div class="">Lets take for example this API:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">+ (</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSInteger</span><span style="font-variant-ligatures: no-common-ligatures" class="">)writePropertyList:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">id</span><span style="font-variant-ligatures: no-common-ligatures" class="">)plist toStream:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">NSOutputStream</span><span style="font-variant-ligatures: no-common-ligatures" class=""> *)stream format:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">NSPropertyListFormat</span><span style="font-variant-ligatures: no-common-ligatures" class="">)format options:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">NSPropertyListWriteOptions</span><span style="font-variant-ligatures: no-common-ligatures" class="">)opt error:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">out</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">NSError</span><span style="font-variant-ligatures: no-common-ligatures" class=""> **)error;</span></div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">The return value here would be 0 if an error occurs. So the nullability value would be 0.</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">+ (</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">nullable</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</span><span style="font-variant-ligatures: no-common-ligatures" class="">) NSInteger)</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">writePropertyList</span><span style="font-variant-ligatures: no-common-ligatures" class="">:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">id</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">plist</span><span style="font-variant-ligatures: no-common-ligatures" class=""> toStream:(NSOutputStream *)</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">stream</span><span style="font-variant-ligatures: no-common-ligatures" class=""> format:(NSPropertyListFormat)</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">format</span><span style="font-variant-ligatures: no-common-ligatures" class=""> options:(NSPropertyListWriteOptions)opt error:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">out</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #78492a" class="">NSError</span><span style="font-variant-ligatures: no-common-ligatures" class=""> **)error;</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">But other APIs like you indicated:</span></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">- (<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSUInteger</span>)indexOfObject:(ObjectType)anObject;</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">Could be converted to:</span></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">- (<span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">nullable</span>(NSNotFound) NSUInteger)indexOfObject:(ObjectType)anObject;</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">Which would immediately be an indication to the reader what the&nbsp;“null” value would be represented as. Of course your concept of type aliases might be a decent way to group concepts together but if lets say there was an index type for NSArray; obviously you might want a index return value to be nullable but it would be a bit confusing to take a nullable parameter into certain APIs.</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">Given a concept of NSArrayIndex as you suggested (that being nullable) would have the problem that&nbsp;</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">- (ObjectType)objectAtIndex:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">NSUInteger</span><span style="font-variant-ligatures: no-common-ligatures" class="">)index;</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">Would either incorrectly indicate it would be nullable or it would have a different type.&nbsp;</span></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></span></div><div style="margin: 0px; line-height: normal;" class="">There would be other cases where structural types might need a nullable placeholder value, e.g. NSRange with a location of NSNotFound and a length of 0 (however that strictly isn’t correct since it is just the location that indicates null-ness.. but that is probably more of an implementation detail and should probably be corrected imho).</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">There could also be cases where an API returns either an object of a specific type or NSNull as a placeholder. This would be nice to be able to express as a nullable type especially in generics. For example: `NSArray&lt;_Nullable(NSNull *) Foo *&gt; *` could be a neat way to express `Array&lt;Foo?&gt;` which cannot be expressed currently.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Overall I think this could really reduce some of the overlays for all the frameworks on Mac OS X and iOS, improve the expressivity of Objective-C APIs, offer more accurate bridged representations, and generally give API authors an opportunity to more correctly represent what should be exposed in Swift without needing to write overlays that could easily have poor interaction with things like subclassing or delegation.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">As a side note: I am not certain if the parameterization of nullability annotations would even be possible in the current compiler implementations or if it would be easier to use an attribute instead (that would be left to implementation detail).</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">I would guess that if this feature would be available it would take a combined effort from all API maintainers to annotate their return values and any un-annotated shouldn’t be exposed as a IOU since they have non nil values already. Furthermore the timeframe to do so would probably be independent of the implementation of this type of feature.&nbsp;</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Those caveats aside - I think it would be a fantastic tool in the toolbox!</div></span></div></div><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 14, 2017, at 10:41 AM, Jeff Kelley 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=""><div dir="ltr" class="">On Mon, Feb 13, 2017 at 11:53 PM, Rod Brown <span dir="ltr" class="">&lt;<a href="mailto:rodney.brown6@icloud.com" target="_blank" class="">rodney.brown6@icloud.com</a>&gt;</span> wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="auto" class=""><div class="">I think the biggest problem we're going to face with this one is changes to Objective-C are out of scope for Swift Evolution. Apple tend to be the ones in control of the development of new Objective-C features and compatibility because they control the compiler.</div></div></blockquote><div class=""><br class=""></div><div class="">I don’t think that Objective-C changes are out of bounds when Swift is involved—see my past, accepted proposal at <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0033-import-objc-constants.md" class="">SE-0033</a>.</div><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="auto" class=""><div id="gmail-m_-8936043654950753604AppleMailSignature" class="">That said, as a request to Apple for this change, I think it's a reasonable idea for Ints, but I'm not sure of its feasibility for other types. Could the API be descriptive enough to cover enough types? (Eg CGRectNull)<br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">It’s an open-and-shut case for any standard primitive, but structs like <font face="monospace, monospace" class="">CGRect</font> are where it starts to get tricky. I see that <font face="monospace, monospace" class="">CGRect</font> conforms to <font face="monospace, monospace" class="">Equatable</font> when it’s imported into Swift; perhaps that could be enough for this to work? If the translation to and from <font face="monospace, monospace" class="">nil</font> happens in the Swift side, I can see <font face="monospace, monospace" class="">Equatable</font> as a reasonable requirement for the type.</div><div class=""><br class=""></div><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="auto" class=""><div id="gmail-m_-8936043654950753604AppleMailSignature" class=""></div><div class=""><div class="gmail-h5"><div id="gmail-m_-8936043654950753604AppleMailSignature" class="">On 14 Feb 2017, at 2:33 pm, Jeff Kelley via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">Hi all,<div class=""><br class=""></div><div class=""><span class="gmail-m_-8936043654950753604gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>I don’t have a formal proposal written up yet, but in my continued quest to make better-annotated Objective-C code, I had an idea for bridging <font face="monospace, monospace" class="">nil</font> with primitives. Since in Objective-C we often use constant values to represent invalid values or&nbsp;<font face="monospace, monospace" class="">nil</font>, the most obvious being <font face="monospace, monospace" class="">NSNotFound</font>, could we use that as a shorthand for <font face="monospace, monospace" class="">nil</font>? Something like this for <font face="monospace, monospace" class="">NSArray</font>:</div><div class=""><br class=""></div><div class=""><font face="monospace, monospace" class="">- (NSUInteger NS_SWIFT_NIL(NSNotFound))<wbr class="">indexOfObject:(ObjectType)<wbr class="">anObject;</font></div><div class=""><br class=""></div><div class=""><span class="gmail-m_-8936043654950753604gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>This is a little verbose, so it could also work with a <font face="monospace, monospace" class="">typedef</font>:</div><div class=""><br class=""></div><div class=""><font face="monospace, monospace" class="">typedef NSUInteger NS_SWIFT_NIL(NSNotFound) NSArrayIndex;</font></div><div class=""><font face="monospace, monospace" class="">- (NSArrayIndex)indexOfObject:(<wbr class="">ObjectType)anObject;</font><br class=""></div><div class=""><br class=""></div><div class=""><span class="gmail-m_-8936043654950753604Apple-tab-span" style="white-space:pre-wrap">        </span>This would change the existing Swift interface to return an <font face="monospace, monospace" class="">Int?</font> instead of an <font face="monospace, monospace" class="">Int</font>. I see this as working both ways—converting these values to <font face="monospace, monospace" class="">nil</font> when returning from Objective-C to Swift, and sending these values instead of <font face="monospace, monospace" class="">nil</font> when Swift calls into Objective-C code.</div><div class=""><br class=""></div><div class=""><span class="gmail-m_-8936043654950753604Apple-tab-span" style="white-space:pre-wrap">        </span>Is this worth writing up a proposal for? Is another, better method already in someone’s mind?</div><div class=""><br clear="all" class=""><div class=""><div class="gmail-m_-8936043654950753604gmail_signature"><div dir="ltr" class=""><div style="font-family:helvetica" class=""><br class=""></div><div style="font-family:helvetica" class="">Jeff Kelley</div><div style="font-family:helvetica" class=""><br class=""></div><div style="font-family:helvetica" class=""><a href="mailto:SlaunchaMan@gmail.com" style="color:rgb(17,85,204)" target="_blank" class="">SlaunchaMan@gmail.com</a>&nbsp;|&nbsp;<a href="https://twitter.com/SlaunchaMan" style="color:rgb(17,85,204)" target="_blank" class="">@<wbr class="">SlaunchaMan</a>&nbsp;|&nbsp;<a href="http://jeffkelley.org/" style="color:rgb(17,85,204)" target="_blank" class="">jeffkelley.org</a></div></div></div></div></div></div></div></blockquote></div></div></div></blockquote></div><br class=""></div><div class="gmail_extra"><br clear="all" class=""><div class=""><div class="gmail_signature"><div dir="ltr" class=""><div style="font-family:helvetica" class=""><br class=""></div><div style="font-family:helvetica" class="">Jeff Kelley</div><div style="font-family:helvetica" class=""><br class=""></div><div style="font-family:helvetica" class=""><a href="mailto:SlaunchaMan@gmail.com" target="_blank" class="">SlaunchaMan@gmail.com</a>&nbsp;|&nbsp;<a href="https://twitter.com/SlaunchaMan" target="_blank" class="">@SlaunchaMan</a>&nbsp;|&nbsp;<a href="http://jeffkelley.org/" target="_blank" class="">jeffkelley.org</a></div></div></div></div><br class=""></div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>