[swift-evolution] Swift's Optional Int as NSNumber in Objective-C

Philippe Hausler phausler at apple.com
Sat May 20 13:58:37 CDT 2017



> On May 20, 2017, at 12:25 AM, David Waite via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I believe behavior depends on whether the NSNumber is the objc type or swift subtype, and whether you call the NSNumber.intValue or use Int.init?(exactly: NSNumber).
> 

That part of the behavior is no longer the case. The bridge only transacts upon one number type (to leverage tagged pointers) and the subclass was removed (since it caused some gnarly inconsistencies) 

> My point is that there is no intuitive or safe generalized behavior for treating arbitrary NSNumbers as an Int? . If an application or library wants to accept a NSNumber and treat it as an Int?, it should be responsible for declaring that method and implementing that logic.

But you are absolutely correct; NSNumber should be though of as a AnyNumericValue box where the type of the number is erased but the value is not.

Interesting cases include:

NSNumber(value: 3.0) as? Int == 3

Or 

NSNumber(value: UInt64(121)) as? Int8 == Int8(121)

The SE-0170 proposal also added initializers for truncating and exactly that work much more on par with the rest of the numeric system in swift. (However it did un-cover a few nasty floating point bugs in the unit tests but the intent of the behavior is matched)

The other consideration that might be interesting to further your point that nullable NSNumber * as a representation of Int? Is a bit off is that often “optional” integers in objc are actually PoD types with sentry values; e.g. NSNotFound etc. So in reality we would need some sort of annotation on how the bridge of a numeric type should be represented to indicate a nullable value that is exposed as an integer or float etc.

> 
> -DW
> 
>> On May 19, 2017, at 11:04 PM, Jonathan Hull <jhull at gbis.com <mailto:jhull at gbis.com>> wrote:
>> 
>> What happens now if you call integerValue if a NSNumber has these values?
>> 
>> 
>>> On May 19, 2017, at 9:00 PM, David Waite <david at alkaline-solutions.com <mailto:david at alkaline-solutions.com>> wrote:
>>> 
>>> When I call such a mapped Swift API that expects an Int? parameter from Objc with a NSNumber initialized with 3.5, what should happen? 
>>> 
>>> [NSNumber uint64value: UINT64_MAX] ?
>>> 
>>> What about the float 1e100? 
>>> 
>>> What about boolean 'true’? 
>>> 
>>> NaN?
>>> 
>>> -DW
>>> 
>>>> On May 19, 2017, at 8:54 PM, Jonathan Hull via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>> 
>>>> I have to side with Kenny on this one.  I would find losing nil vs 0 more surprising than NSInteger vs NSNumber.  In fact, I was surprised that this doesn’t already cross to a NSNumber. That would be the behavior I expect.
>>>> 
>>>> Thanks,
>>>> Jon
>>>> 
>>>> 
>>>>> On May 16, 2017, at 11:51 AM, Kenny Leung via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>> 
>>>>> But my argument *is* that optionality is an obvious way to make that decision.
>>>>> 
>>>>> If I was writing in pure Objective-C (outside the context of Swift), sometimes I would have methods that take or return int, and sometimes I would have methods that take or return NSNumber. There is never really a surprise as to why. So why would there be a surprise when bridging from Swift?
>>>>> 
>>>>> -Kenny
>>>>> 
>>>>> 
>>>>>> On May 15, 2017, at 7:24 AM, T.J. Usiyan <griotspeak at gmail.com <mailto:griotspeak at gmail.com>> wrote:
>>>>>> 
>>>>>> The argument is not about whether or not it should come through as an object. The argument is about the fact that *sometimes* it would come through as an object and other times it would not. Optionality isn't an obvious way to make that decision.
>>>>>> 
>>>>>> TJ
>>>>>> 
>>>>>> On Mon, May 15, 2017 at 3:03 PM, Charlie Monroe <charlie at charliemonroe.net <mailto:charlie at charliemonroe.net>> wrote:
>>>>>> This is not much of an argument given that NSString is an object in ObjC (heap-allocated), String in Swift is an struct and also given that most NSNumber's nowadays are not really allocated, but just tagged pointers.
>>>>>> 
>>>>>> Given that NSNumber is immutable, you get the value semantics anyway...
>>>>>> 
>>>>>>> On May 15, 2017, at 1:09 PM, T.J. Usiyan via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>>> 
>>>>>>> My understanding of the reasoning is that `NSNumber` is an object in Objective-C and not a struct. There is already one level of decision when translating to objc in that regard. Switching between reference semantics/class and value semantics because of optionality is surprising.
>>>>>>> 
>>>>>>> On Mon, May 15, 2017 at 5:52 AM, Kenny Leung via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>>> > On May 12, 2017, at 9:56 AM, John McCall via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>>> 
>>>>>>> > Exporting Int? as an optional NSNumber does not feel obvious and idiomatic when we would export Int as NSInteger.  It feels like reaching for an arbitrary solution.
>>>>>>> 
>>>>>>> I don’t understand this reasoning. I’ve had cause to distinguish 0 from null in both Objective-C and Java, and I would do exactly the same thing.
>>>>>>> 
>>>>>>> -Kenny
>>>>>>> 
>>>>>>> _______________________________________________
>>>>>>> swift-evolution mailing list
>>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>> 
>>>>>>> _______________________________________________
>>>>>>> swift-evolution mailing list
>>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>> 
>>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170520/c05fcfe5/attachment.html>


More information about the swift-evolution mailing list