> On Aug 24, 2016, at 4:16 AM, David Rönnqvist <david.ronnqv...@gmail.com> 
> wrote:
> 
> I have some problems understanding the scope of this proposal. More 
> specifically if it’s limited to arrays and dictionaries or if it’s broader 
> than that, and if it’s limited to objects that originate in Swift or if the 
> same applies for objects that originate in Objective-C code.

It’s broader than that. It affects any Optional value that is put into an ‘Any’ 
and passed to Objective-C. Note, however, that if you have a nullable parameter 
in Objective-C, e.g.,

        -(void)methodWithObject:(nullable id)object;

Which comes into Swift as

        func method(with object: Any?)

Then ‘nil’ will be passed through as ‘nil’. This only affects the case where 
you’re passing a Swift optional to a non-optional parameter:

        -(void)methodWithNonNullObject:(nonnull id)object;

        func method(withNonNullObject object: Any)

> 
> For me, it makes sense that Swift arrays of type [C?] and [Any] would bridge 
> to Objective-C as NSArrays bridge nils to NSNull. That feels like the most 
> natural way of representing those missing values in Objective-C. 

Right. The alternative is that nil values bridge to an opaque box type known 
only to the Swift runtime. NSNull seems strictly better here, because 
Objective-C code can reason about it.

> For dictionaries of type [K:C?] and [K:Any] I feel that bridging Swift nils 
> to NSNull is pretty straight forward and allows for the distinction of a key 
> with no value and a key with an explicit nil value. However, I feel that the 
> same doesn’t work in the other direction. If a NSNull value in an Objective-C 
> NSDictionary would bridge to a nil value it wouldn’t be possible to 
> distinguish between a key without a value and key with a nil value (something 
> one might have to do when checking the KVO change dictionary).  

NSNulls are handled dynamically. If you wanted to check whether Objective-C put 
an ‘NSNull’ in there explicitly, you can do so with “as? NSNull”.  If instead 
you do “as? SomeType?”, the NSNull will become the ‘nil’ value in the SomeType.

> 
> There are also some APIs that make a distinction between NSNull and nil, for 
> example action(for:forKey:) on CALayerDelegate. Does this proposal have any 
> impact on those APIs?

That method returns “CAAction?”, so ‘nil’ will come through as ‘nil’ and NSNull 
can be stored in the .some(x).

        - Doug

> 
> - David
> 
>> On 24 Aug 2016, at 00:36, Douglas Gregor via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Introduction
>> 
>> Optionals can be used as values of the type Any, but only bridge as opaque 
>> objects in Objective-C. We should bridge Optionals with some value by 
>> bridging the wrapped value, and bridge nils to the NSNull singleton.
>> 
>> Swift-evolution thread: TBD 
>> <https://lists.swift.org/pipermail/swift-evolution/>
>>  
>> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-optional-to-nsnull.md#motivation>Motivation
>> 
>> SE-0116 
>> <https://github.com/apple/swift-evolution/blob/master/proposals/0116-id-as-any.md>
>>  changed how Objective-C's id and untyped collections import into Swift to 
>> use the Any type. This makes it much more natural to pass in Swift value 
>> types such as String and Array, but introduces the opportunity for 
>> optionality mismatches, since an Any can contain a wrapped Optional value 
>> just like anything else. Our current behavior, where Optional is given only 
>> the default opaque bridging behavior, leads to brittle transitivity problems 
>> with collection subtyping. For example, an array of Optional objects bridges 
>> to an NSArray of opaque objects, unusable from ObjC:
>> 
>> class C {}
>> let objects: [C?] = [C(), nil, C()]
>> The more idiomatic mapping would be to use NSNull or some other sentinel to 
>> represent the missing values (since NSArray cannot directly store nil). 
>> Counterintuitively, this is in fact what you get if you bridge an array of 
>> Any with nil elements:
>> 
>> class C {}
>> let objects: [Any] = [C(), nil as C?, C()]
>> though with an opaque box taking the place of the standard NSNull sentinel. 
>> Since there's a subtype relationship between T and Optional<T>, it's also 
>> intuitive to expect that the bridging operation be consistent between T and 
>> occupied values of Optional<T>.
>> 
>>  
>> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-optional-to-nsnull.md#proposed-solution>Proposed
>>  solution
>> 
>> When an Optional<T> value is bridged to an Objective-C object, if it 
>> contains some value, that value should be bridged; otherwise, NSNull or 
>> another sentinel object should be used.
>> 
>>  
>> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-optional-to-nsnull.md#detailed-design>Detailed
>>  design
>> 
>> some maps to the bridged value
>> none maps to NSNull
>> if we don't want to lose information about nested optionals, we'd need a 
>> unique SwiftNull object for every optional type, so that .some(.none) maps 
>> to NSNull and .none maps to SwiftNull(T?)
>>  
>> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-optional-to-nsnull.md#impact-on-existing-code>Impact
>>  on existing code
>> 
>> This change has no static source impact, but changes the dynamic behavior of 
>> the Objective-C bridge. From Objective-C's perspective, Optionals that used 
>> to bridge as opaque objects will now come in as semantically meaningful 
>> Objective-C objects. This should be a safe change, since existing code 
>> should not be relying on the behavior of opaque bridged objects. From 
>> Swift's perspective, values should still be able to round-trip from Optional 
>> to Any to id to Anyand back by dynamic casting.
>> 
>>  
>> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-optional-to-nsnull.md#alternatives-considered>Alternatives
>>  considered
>> 
>> Do nothing
>> Attempt to trap or error when Optionals are used as Anys -- would be good 
>> QoI to warn, but it can't be prevented, and is occasionally desired
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to