[Pitch] Importing Objective-C 'id' as Swift 'Any'


(Joe Groff) #1

Hi everyone. After implementing SE-0072, disabling the implicit bridging conversions from Swift value types to classes (https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md), we immediately observed a severe negative impact on Cocoa interop as our users at Apple adapted to the change, forcing us to roll it back. `id`-based interfaces are still all over the place in the Cocoa SDKs, but it's our goal that Swift programmers should be able to use the value type versions of things without being constantly confronted with marshalling in and out of their `NS` versions, and this change failed that test for Cocoa users. Furthermore, the Foundation corelibs team is interested in continuing to adopt more value types and improving the experience of using Foundation from Swift without being hamstrung by the limitations of ObjC interop. We can address the problem of value-type-to-id interfacing in a different way—instead of making it a special case in the type system, we can handle it in the Objective-C bridge instead, by bridging Objective-C's `id` type to `Any` instead of `AnyObject`. This is a big change, but I think it leads to an overall Swiftier and more flexible model. I'm working on a proposal to this effect and would like to start getting feedback on it. Thanks for taking a look!

https://github.com/jckarter/swift-evolution/blob/1316004246e45296f81582477d70c22f95ec106c/proposals/XXXX-id-as-any.md

-Joe


(TJ Usiyan) #2

+1 from me

I think that it makes sense since there exists now a possibility for Obj-C
types to come in as types with value semantics.

TJ

···

On Fri, Jul 1, 2016 at 7:37 PM, Joe Groff via swift-evolution < swift-evolution@swift.org> wrote:

Hi everyone. After implementing SE-0072, disabling the implicit bridging
conversions from Swift value types to classes (
https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md),
we immediately observed a severe negative impact on Cocoa interop as our
users at Apple adapted to the change, forcing us to roll it back.
`id`-based interfaces are still all over the place in the Cocoa SDKs, but
it's our goal that Swift programmers should be able to use the value type
versions of things without being constantly confronted with marshalling in
and out of their `NS` versions, and this change failed that test for Cocoa
users. Furthermore, the Foundation corelibs team is interested in
continuing to adopt more value types and improving the experience of using
Foundation from Swift without being hamstrung by the limitations of ObjC
interop. We can address the problem of value-type-to-id interfacing in a
different way—instead of making it a special case in the type system, we
can handle it in the Objective-C bridge instead, by bridging Objective-C's
`id` type to `Any` instead of `AnyObject`. This is a big change, but I
think it leads to an overall Swiftier and more flexible model. I'm working
on a proposal to this effect and would like to start getting feedback on
it. Thanks for taking a look!

https://github.com/jckarter/swift-evolution/blob/1316004246e45296f81582477d70c22f95ec106c/proposals/XXXX-id-as-any.md

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #3

I'm really happy to see this. It cleans things up and enables some really important things such as more idiomatic bridging (NSNumber to native numeric types is amazing!). The ideas mentioned will really help to make Cocoa feel as Swifty as possible.

···

Sent from my iPad

On Jul 1, 2016, at 6:37 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Hi everyone. After implementing SE-0072, disabling the implicit bridging conversions from Swift value types to classes (https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md), we immediately observed a severe negative impact on Cocoa interop as our users at Apple adapted to the change, forcing us to roll it back. `id`-based interfaces are still all over the place in the Cocoa SDKs, but it's our goal that Swift programmers should be able to use the value type versions of things without being constantly confronted with marshalling in and out of their `NS` versions, and this change failed that test for Cocoa users. Furthermore, the Foundation corelibs team is interested in continuing to adopt more value types and improving the experience of using Foundation from Swift without being hamstrung by the limitations of ObjC interop. We can address the problem of value-type-to-id interfacing in a different way—instead of making it a special case in the type system, we can handle it in the Objective-C bridge instead, by bridging Objective-C's `id` type to `Any` instead of `AnyObject`. This is a big change, but I think it leads to an overall Swiftier and more flexible model. I'm working on a proposal to this effect and would like to start getting feedback on it. Thanks for taking a look!

https://github.com/jckarter/swift-evolution/blob/1316004246e45296f81582477d70c22f95ec106c/proposals/XXXX-id-as-any.md

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Waite) #4

+1!

To me, it feels like the ambivalent dynamic casting is a temporary complexity, and that at some point in the future the need to expose legacy reference types like NSString outside swift-supplied or user-created bridging code will disappear completely.

This also will get rid of some of the rough edges in the various corelibs where value types cannot be supported because some platforms have a backing library written in Objective-C. Swiftier indeed!

Is this something you are pushing for in Swift 3? It seems appropriate but ambitious.

Just to cement my own understanding of the ambivalent dynamic casting - would the behavior be similar if the clang importer took id references and embedded them into a Bridgeable wrapper to defer bridging, and this Bridgeable wrapper (as well as Array, Dictionary and Set) was understood by the language to participate in as‽ behavior?

-DW

···

On Jul 1, 2016, at 5:37 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Hi everyone. After implementing SE-0072, disabling the implicit bridging conversions from Swift value types to classes (https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md), we immediately observed a severe negative impact on Cocoa interop as our users at Apple adapted to the change, forcing us to roll it back. `id`-based interfaces are still all over the place in the Cocoa SDKs, but it's our goal that Swift programmers should be able to use the value type versions of things without being constantly confronted with marshalling in and out of their `NS` versions, and this change failed that test for Cocoa users. Furthermore, the Foundation corelibs team is interested in continuing to adopt more value types and improving the experience of using Foundation from Swift without being hamstrung by the limitations of ObjC interop. We can address the problem of value-type-to-id interfacing in a different way—instead of making it a special case in the type system, we can handle it in the Objective-C bridge instead, by bridging Objective-C's `id` type to `Any` instead of `AnyObject`. This is a big change, but I think it leads to an overall Swiftier and more flexible model. I'm working on a proposal to this effect and would like to start getting feedback on it. Thanks for taking a look!

https://github.com/jckarter/swift-evolution/blob/1316004246e45296f81582477d70c22f95ec106c/proposals/XXXX-id-as-any.md

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Daniel Duan) #5

Joe Groff via swift-evolution <swift-evolution@...> writes:

+1. id => AnyObject made more sense then just as id =>Any makes more sense now
(now that things from Objective-C have value semantics more commonly).


(Kevin Lundberg) #6

+1, as long as the weird dynamic @objc method lookup behavior on
AnyObject isn't also carried over to Any as part of this proposal. This
behavior is a source of frustration for me as it reduces how much I can
reason about code i work with when it creeps in unknowingly, and I don't
even like properties being exposed (which option 3 suggests), since
that's where I see it come up most often day to day. I'd personally like
to see it go away completely.

I brought this up on the list a few months ago but I ended up not being
able to pursue a proposal at the time. However, my idea was that if we
need to keep dynamic lookup around, a dedicated protocol could have this
behavior applied to it, so that API consumers who need it could
explicitly opt into using the dynamic method lookup:

@objc protocol ObjcObject {} // defined in the stdlib/overlay/wherever
it makes the most sense

(Foo.foo() as ObjcObject).someDynamicallyDiscoveredMethod()

This has the added benefit of notifying readers of the code that it
isn't portable, since the type of the value is made explicit as one that
only is allowed in obj-c. Would this be a satisfactory solution to the
problem if this behavior needs to stay in place?

- Kevin

···

On 7/1/2016 7:37 PM, Joe Groff via swift-evolution wrote:

Hi everyone. After implementing SE-0072, disabling the implicit bridging conversions from Swift value types to classes (https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md), we immediately observed a severe negative impact on Cocoa interop as our users at Apple adapted to the change, forcing us to roll it back. `id`-based interfaces are still all over the place in the Cocoa SDKs, but it's our goal that Swift programmers should be able to use the value type versions of things without being constantly confronted with marshalling in and out of their `NS` versions, and this change failed that test for Cocoa users. Furthermore, the Foundation corelibs team is interested in continuing to adopt more value types and improving the experience of using Foundation from Swift without being hamstrung by the limitations of ObjC interop. We can address the problem of value-type-to-id interfacing in a different way—instead of making it a special case in the type system, we can handle it in the Objective-C bridge instead, by bridging Objective-C's `id` type to `Any` instead of `AnyObject`. This is a big change, but I think it leads to an overall Swiftier and more flexible model. I'm working on a proposal to this effect and would like to start getting feedback on it. Thanks for taking a look!

https://github.com/jckarter/swift-evolution/blob/1316004246e45296f81582477d70c22f95ec106c/proposals/XXXX-id-as-any.md

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #7

Yes, we’re trying for it. “Appropriate but ambitious” is an accurate assessment - this is a huge stretch by the entire team but Swift 3 is the right time for it.

-Chris

···

On Jul 1, 2016, at 9:11 PM, David Waite via swift-evolution <swift-evolution@swift.org> wrote:

+1!

To me, it feels like the ambivalent dynamic casting is a temporary complexity, and that at some point in the future the need to expose legacy reference types like NSString outside swift-supplied or user-created bridging code will disappear completely.

This also will get rid of some of the rough edges in the various corelibs where value types cannot be supported because some platforms have a backing library written in Objective-C. Swiftier indeed!

Is this something you are pushing for in Swift 3? It seems appropriate but ambitious.


(Matthew Johnson) #8

+1!

To me, it feels like the ambivalent dynamic casting is a temporary complexity, and that at some point in the future the need to expose legacy reference types like NSString outside swift-supplied or user-created bridging code will disappear completely.

This also will get rid of some of the rough edges in the various corelibs where value types cannot be supported because some platforms have a backing library written in Objective-C. Swiftier indeed!

Is this something you are pushing for in Swift 3? It seems appropriate but ambitious.

Yes, we’re trying for it. “Appropriate but ambitious” is an accurate assessment - this is a huge stretch by the entire team but Swift 3 is the right time for it.

It looks that way for sure - I was surprised to see this so late in the cycle. I really appreciate the team devoting the effort to try and get it done now. It will make a big difference.

···

Sent from my iPad

On Jul 2, 2016, at 12:21 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 1, 2016, at 9:11 PM, David Waite via swift-evolution <swift-evolution@swift.org> wrote:

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Goffredo Marocchi) #9

Hey Chris,

Do you have plans to allow people to update Swift outside Xcode 8 point updates and still be able to submit to the App Store and benefit from the IDE's features? This could allow bug fixes to be delivered on a swifter way and take advantage of the fact that iOS is not including the runtime yet.

···

Sent from my iPhone

On 2 Jul 2016, at 06:21, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 1, 2016, at 9:11 PM, David Waite via swift-evolution <swift-evolution@swift.org> wrote:

+1!

To me, it feels like the ambivalent dynamic casting is a temporary complexity, and that at some point in the future the need to expose legacy reference types like NSString outside swift-supplied or user-created bridging code will disappear completely.

This also will get rid of some of the rough edges in the various corelibs where value types cannot be supported because some platforms have a backing library written in Objective-C. Swiftier indeed!

Is this something you are pushing for in Swift 3? It seems appropriate but ambitious.

Yes, we’re trying for it. “Appropriate but ambitious” is an accurate assessment - this is a huge stretch by the entire team but Swift 3 is the right time for it.

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Shawn Erickson) #10

It does look like a huge benefit for many many current swift users. Thanks
to the whole team trying to make this happen in Swift 3.

···

On Fri, Jul 1, 2016 at 10:21 PM Chris Lattner via swift-evolution < swift-evolution@swift.org> wrote:

> On Jul 1, 2016, at 9:11 PM, David Waite via swift-evolution < > swift-evolution@swift.org> wrote:
>
> +1!
>
> To me, it feels like the ambivalent dynamic casting is a temporary
complexity, and that at some point in the future the need to expose legacy
reference types like NSString outside swift-supplied or user-created
bridging code will disappear completely.
>
> This also will get rid of some of the rough edges in the various
corelibs where value types cannot be supported because some platforms have
a backing library written in Objective-C. Swiftier indeed!
>
> Is this something you are pushing for in Swift 3? It seems appropriate
but ambitious.

Yes, we’re trying for it. “Appropriate but ambitious” is an accurate
assessment - this is a huge stretch by the entire team but Swift 3 is the
right time for it.

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #11

Hey Chris,

Do you have plans to allow people to update Swift outside Xcode 8 point updates and still be able to submit to the App Store and benefit from the IDE's features? This could allow bug fixes to be delivered on a swifter way and take advantage of the fact that iOS is not including the runtime yet.

We don’t discuss Xcode future direction on the Swift lists, even though there is often overlap with the future of Swift. OTOH, the future and direction of Swift is totally on topic for these lists.

-Chris

···

On Jul 2, 2016, at 1:20 AM, Goffredo Marocchi <panajev@gmail.com> wrote:

Sent from my iPhone

On 2 Jul 2016, at 06:21, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 1, 2016, at 9:11 PM, David Waite via swift-evolution <swift-evolution@swift.org> wrote:

+1!

To me, it feels like the ambivalent dynamic casting is a temporary complexity, and that at some point in the future the need to expose legacy reference types like NSString outside swift-supplied or user-created bridging code will disappear completely.

This also will get rid of some of the rough edges in the various corelibs where value types cannot be supported because some platforms have a backing library written in Objective-C. Swiftier indeed!

Is this something you are pushing for in Swift 3? It seems appropriate but ambitious.

Yes, we’re trying for it. “Appropriate but ambitious” is an accurate assessment - this is a huge stretch by the entire team but Swift 3 is the right time for it.

-Chris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution