[swift-evolution] [Idea] Further directions for id-as-Any

Joe Groff jgroff at apple.com
Tue Sep 6 19:40:39 CDT 2016


> On Sep 6, 2016, at 5:19 AM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org> wrote:
> 
> In the current Swift 3 betas, value types can now be passed into Objective-C as opaque box objects. A couple of reviews are currently running which tweak this bridging, exposing Optionals and NSValue/NSNumber-compatible types in more natural ways. These are all Good Things. I'd like to look ahead and sketch out a way this feature could evolve further. This will not be detailed, and much or all of it may be out of scope for Phase 1.
> 
> 
> Firstly, I think we could make boxed value types much more usable from Objective-C:
> 
> 1. We could bridge selector calls to equivalent Swift methods, where those methods are Objective-C-compatible (other than being on a value type). This could actually be done dynamically if enough metadata is available.
> 
> 2. We could generate a separate subclass of our box class for each bridged Swift type. This could actually *still* be done dynamically, I believe.
> 
> 3. We could permit value types to conform to @objc protocols. This would open up several nice features to us; perhaps most importantly, a value type could conform to NSCoding and thereby participate in Foundation's serialization mechanisms. I suspect that at this point, the box subclasses would have to become "real", i.e., registered at load time. (Perhaps they're only greedily registered if they have an explicit @objc?)
> 
> 4. We could explicitly declare the bridged methods, properties, and conformances in the generated -Swift.h file, thereby making Swift value types directly available to Objective-C, where they can be allocated, accessed, and manipulated in boxed form.
> 
> 
> Secondly—and separately, but relatedly—I believe a few simple changes could liberalize the @objc-compatibility rules, permitting many more members to be exposed to Objective-C:
> 
> 1. We could run "omit needless words" in reverse when exposing Swift methods to Objective-C. This would prevent overloads from clashing in Objective-C, and would also have the bonus feature of producing more idiomatic Objective-C interfaces. (Incidentally, is a change considered source-breaking if it breaks Objective-C code, not Swift code?)
> 
> 2. We could grant access to members using Swift-only type features by allowing the Objective-C versions to have looser types than the Swift versions, and dynamically enforcing the missing constraints instead. For instance, a member with a complicated `where` clause might omit the clause in its Objective-C declaration, but enforce it with a dynamic test.
> 
> 3. I suspect it might be possible to expose generic types to Objective-C with some custom class methods. For instance, a Swift type with `Key` and `Value` type parameters might have `+classWithKey:(Class)keyClass value:(Class)valueClass` and +`allocWithKey:(Class)keyClass value:(Class)valueClass` methods on it.
> 
> 
> Are these potential features of interest? If so, to what extent do they affect binary compatibility? On the one hand, they are extensions, adding transparency to things which are currently opaque. But on the other hand, they will presumably involve generating type metadata.

Yeah, this is definitely a direction that at least I am interested in. Letting value types conform to @objc protocols and have @objc methods would be especially empowering for Cocoa APIs. There are some subtleties—many ObjC protocols are *intended* to be class-constrained, particularly delegate protocols, and these protocols also tend to be used as weak references and other concepts that only really make sense for classes. Your point (4) also raises a question of whether Swift value types ought to be exposed to ObjC in their boxed or unboxed forms; it seems to me that there are many structs that you'd want to export back to C or ObjC as plain structs and not boxed objects. We're also still researching the backward compatibility ramifications of changing the bridging model. While at face value, these ought to be additive changes, since we're turning purportedly opaque ObjC objects into meaningful ones, and relaxing generic constraints, the fact of the matter is people can and do rely on implementation details that are supposed to be private and subject to change. I'm hopeful we can explore this model going forward, though.

-Joe


More information about the swift-evolution mailing list