[swift-evolution] [Proposal draft] Bridge Optional As Its Payload Or NSNull
David Hart
david at hartbit.com
Fri Aug 26 01:12:54 CDT 2016
For what it’s worth, I’m very much behind this proposal. +1
> On 24 Aug 2016, at 00:36, Douglas Gregor via swift-evolution <swift-evolution at 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 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/20160826/256e752a/attachment.html>
More information about the swift-evolution
mailing list