[swift-evolution] [Idea] Further directions for id-as-Any
brent at architechies.com
Tue Sep 6 07:19:54 CDT 2016
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.
More information about the swift-evolution