> 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