> https://github.com/apple/swift-evolution/blob/master/proposals/0058-objectivecbridgeable.md

>    But then, these *are* intended to be full-width type conversions,
>    are they not?  Why not these:
> 
>      init?(_ source: ObjectiveCType)
>      init(_ source: ObjectiveCType?)
> 
>    ?  If any of these transformations are wrong, it would good to have
>    a rationale as to why.

I really don't like these two differing only by the optionality of their 
argument and return type, especially if they're going to have *no* argument 
label, which will make them look very attractive. And the unconditional one has 
many strange semantics—the extra layer of optionality on the argument, the fact 
that it may *lazily* crash if you access a sub-object which isn't permitted, 
etc. So I would at least label that one:

        init?(_ source: ObjectiveCType)
        init(forced source: ObjectiveCType?)

I'm also a little worried about having an `init?(_:)` when a particular 
conversion might reasonably always succeed. The lack of a label will imply to 
users that this is something they can use directly; 

> 3. Is this proposal introducing a backdoor people can exploit to create
>   user-defined implicit conversions?  If so, shouldn't that worry us?

This proposal reads to me like it permits conversions by casting, but not by 
simply using one type where another belongs.

> 4. This proposal should probably support creating a type that only
>   bridges *from* Objective-C, to handle bridging mutable Objective-C
>   classes without an immutable base class to value types (anything else
>   breaks one of the languages' expectations of value or reference
>   semantics).  This suggests a hierarchy of two protocols might be
>   warranted.

I agree.

Here's an alternative design. It does a few things:

* Splits bridging from and bridging to Objective-C so they can be applied 
independently.
* Splits conditional and unconditional bridging from Objective-C. 
* Explicitly marks Objective-C types with their Swift equivalents, even in 
Swift, to make it clear that each Objective-C type bridges to exactly one Swift 
type, and which type that is. (This allows you to have multiple conversions 
between various Swift types and a single Objective-C type, while explicitly 
specifying which one, if any, should be used when translating Objective-C APIs 
to Swift.)

I'm using the proposed SE-0041 protocol naming conventions 
(https://github.com/apple/swift-evolution/blob/master/proposals/0041-conversion-protocol-conventions.md)
 to name the protocols. I'm also assuming the presence of conditional 
conformances and where clauses on associated types; these protocols would have 
to be temporarily hobbled to work within the type system's current capabilities.

        /// Conforming types can be cast from Self to ObjectiveCType using `as` 
(or a subtype using `as?` 
        /// or `as!`), and Swift APIs taking or returning Self are exposed to 
Objective-C as ObjectiveCType.
        protocol ObjectiveCRepresentable {
                associatedtype ObjectiveCType: AnyObject
                func bridged() -> ObjectiveCType
        }
        
        /// Conforming types can be cast from ObjectiveCType or a subtype to 
Self using `as?` or `as!`.
        /// 
        /// -SeeAlso: ObjectiveCUnconditionallyCreatable, ObjectiveCBridgeable
        protocol ObjectiveCCreatable {
                associatedtype ObjectiveCType: AnyObject
                init?(_ source: ObjectiveCType)
                init(forced source: ObjectiveCType?)
        }
        
        /// Conforming types can be cast from UnconditionalObjectiveCType to 
Self using `as`.
        /// 
        /// -Note:      A type can conform to both this protocol and 
ObjectiveCCreatable to 
        ///             allow both an unconditional exact cast and a 
conditional inexact one. 
        ///             For instance, Array can have ObjectiveCType = 
NSArray<AnyObject> 
        ///             and UnconditionalObjectiveCType = NSArray<T>.
        protocol ObjectiveCUnconditionallyCreatable {
                associatedtype UnconditionalObjectiveCType: AnyObject
                init(_ source: UnconditionalObjectiveCType?)
        }
        
        /// Conforming types are translated from Self to SwiftType in APIs 
imported from Objective-C.
        /// 
        /// -Note:      Objective-C headers can apply this protocol to their 
classes using the
        ///             SWIFT_BRIDGED("SwiftType") attribute.
        /// -Remark: This could instead be indicated with a Swift-side 
attribute.
        protocol ObjectiveCBridgeable: class {
                associatedtype SwiftType: ObjectiveCUnconditionallyCreatable 
where SwiftType.UnconditionalObjectiveCType == Self
        }

Interestingly, another alternative would be to remove the bridging semantic 
from ObjectiveCRepresentable and put it in a subprotocol:

        /// Conforming types can be cast from Self to ObjectiveCType using `as` 
(or a subtype using `as?` 
        /// or `as!`).
        protocol ObjectiveCRepresentable { … }
        
        /// Conforming types will be translated from Self to ObjectiveCType in 
APIs exported to Objective-C
        protocol SwiftToObjectiveCBridgeable: ObjectiveCRepresentable {}
        
        /// Conforming types are translated from Self to SwiftType in APIs 
imported from Objective-C.
        /// 
        /// -Note:      Objective-C headers can apply this protocol to their 
classes using the
        ///             SWIFT_BRIDGED("SwiftType") attribute.
        protocol ObjectiveCToSwiftBridgeable: class {
                associatedtype SwiftType: ObjectiveCUnconditionallyCreatable 
where SwiftType.UnconditionalObjectiveCType == Self
        }

Then the Representable protocol and the two Creatable protocols are no longer 
Objective-C-specific—they simply indicate that a type can be cast to an 
equivalent object type. We can then make them into ObjectRepresentable, 
ObjectCreatable, and ObjectUnconditionalCreatable. (This is good because we 
will presumably want to continue, for instance, casting NSNumber to Int in 
Corelibs Foundation code.)

-- 
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to