[Review] SE-0083: Remove bridging conversion behavior from dynamic casts


(Chris Lattner) #1

Hello Swift community,

The review of "SE-0083: Remove bridging conversion behavior from dynamic casts" begins now and runs through May 16. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0083-remove-bridging-from-dynamic-casts.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and contribute to the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  * What is your evaluation of the proposal?
  * Is the problem being addressed significant enough to warrant a change to Swift?
  * Does this proposal fit well with the feel and direction of Swift?
  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager


(Chéyo Jiménez) #2

Hello Swift community,

The review of "SE-0083: Remove bridging conversion behavior from dynamic casts" begins now and runs through May 16. The proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0083-remove-bridging-from-dynamic-casts.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and contribute to the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  * What is your evaluation of the proposal?

I am for it as long as I am still able to use ``as`` to go from an AnyObject to an NSObject Subclass.

func executeFetchRequest(request: NSFetchRequest <x-quickhelp-usr:c:objc(cs)NSFetchRequest>) throws -> [AnyObject <x-quickhelp-usr:s:Ps9AnyObject>]….
class MyRecipeMO: NSManagedObject {….

….
let existing = try context.executeFetchRequest(fetch) as? [MyRecipeMO]
….

If am not able to do the above then this change would make it much harder to work with Core Data and JSON API

  * Is the problem being addressed significant enough to warrant a change to Swift?

yes

  * Does this proposal fit well with the feel and direction of Swift?

yes

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

seems like casting in java

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

read the email thread.

···

On May 10, 2016, at 11:53 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

More information about the Swift evolution process is available at

  https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Austin Zheng) #3

* What is your evaluation of the proposal?

Strong support.

* Is the problem being addressed significant enough to warrant a change to
Swift?

Yes. Language-level support for bridging between a certain fixed set of
Objective-C and Swift types is surprising behavior, especially since no
other dynamic conversions between otherwise-unrelated types using the
casting keywords are supported by Swift.

* Does this proposal fit well with the feel and direction of Swift?

Very much so. It removes language features that don't have a compelling
reason to exist and replaces them with library initializers that have the
same level of expressiveness. And it is a more sound engineering decision
than the other principled alternative - to open up the dynamic conversion
machinery to allow user-defined conversions.

* If you have used other languages or libraries with a similar feature, how
do you feel that this proposal compares to those?

None. Swift's interoperability story with Objective-C is (to my knowledge)
unprecedented - it is far more involved than (e.g.) Scala interoperating
with Java. The core team has clearly been tracking what works and what
doesn't and making necessary changes as they present themselves, and this
is yet another along that path.

* How much effort did you put into your review? A glance, a quick reading,
or an in-depth study?

Carefully read through the proposal. Considered usage of 'as' and 'as?' in
prior projects, especially in code requiring bridging to/from
NSDictionaries. Read through the related threads.

Best,
Austin

···

On Tue, May 10, 2016 at 11:53 AM, Chris Lattner via swift-evolution < swift-evolution@swift.org> wrote:

Hello Swift community,

The review of "SE-0083: Remove bridging conversion behavior from dynamic
casts" begins now and runs through May 16. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0083-remove-bridging-from-dynamic-casts.md

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at

        https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and contribute to the direction of Swift.
When writing your review, here are some questions you might want to answer
in your review:

        * What is your evaluation of the proposal?
        * Is the problem being addressed significant enough to warrant a
change to Swift?
        * Does this proposal fit well with the feel and direction of Swift?
        * If you have used other languages or libraries with a similar
feature, how do you feel that this proposal compares to those?
        * How much effort did you put into your review? A glance, a quick
reading, or an in-depth study?

More information about the Swift evolution process is available at

        https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Adrian Zubarev) #4

What is your evaluation of the proposal?

This is a welcome change, which also should open the door to rethink the ObjC `AnyObject` protocol and its confusing .Type `AnyClass`.

Is the problem being addressed significant enough to warrant a change to Swift?

Without a doubt. It feels way better and more elegant to use initializers than worrying about what happens under the hood.

Does this proposal fit well with the feel and direction of Swift?

Yes it does. Swift should be a strong type save language, which will apply to remove strange sideeffects like the unwanted bridging in some specific cases. This also will be the next step after SE-0072.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Not that I can think of.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I carefully read the whole proposal and followed the mailing list. I've been waiting for such a change since I faced the unwanted bridging behaviour in one of my projects amost a year ago. The only workaround for checking a type being a reference-type without bridging was `guard instance.dynamicType is AnyObject.Type else`, which is ugly.

···

--
Adrian Zubarev
Sent with Airmail

Am 10. Mai 2016 bei 20:53:15, Chris Lattner via swift-evolution (swift-evolution@swift.org) schrieb:

Hello Swift community,

The review of "SE-0083: Remove bridging conversion behavior from dynamic casts" begins now and runs through May 16. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0083-remove-bridging-from-dynamic-casts.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager.

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and contribute to the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

* What is your evaluation of the proposal?
* Is the problem being addressed significant enough to warrant a change to Swift?
* Does this proposal fit well with the feel and direction of Swift?
* If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
* How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Chris Lattner
Review Manager

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


(Brent Royal-Gordon) #5

  * What is your evaluation of the proposal?

The review is technically over, but I don't believe a decision has been announced yet, so...

I am generally in favor, but I have a serious concern about the readability of certain conversions with this change. To wit, conversions like these:

  myArray as! [NSView]
  myDictionary as! [String: NSView]

Are about to become something more like these:

  [NSView](forcedLazyBridging: myArray)
  [String: NSView](forcedLazyBridging: myDictionary)
  
Or these:

  Array<NSView>(forcedLazyBridging: myArray)
  Dictionary<String, NSView>(forcedLazyBridging: myDictionary)

Either option is a significant regression in code readability compared to the status quo.

It's enough to make me wonder if we shouldn't have special-cased conversion methods for NSArray, NSDictionary, and NSSet:

  myArray.of(NSView) // returns [NSView]
  myDictionary.of(NSView, for: String) // returns [String: NSView]
  mySet.of(NSView) // returns Set<NSView>

On the other hand, if you *don't* have to specify an element type, these aren't so bad:

  Array(forcedLazyBridging: myArray)
  Dictionary(forcedLazyBridging: myDictionary)

And it gets even better if you use something a little saner than `forcedLazyBridging` for the label.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Conversions are a mess, and it'll be nice to clean them up.

  * Does this proposal fit well with the feel and direction of Swift?

Yes.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Most languages I've used have had much simpler cast systems with nothing particularly close to Swift's bridging casts.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading.

···

--
Brent Royal-Gordon
Architechies


(Jordan Rose) #6

I am way late, but I share Brent’s concerns. I don’t think this addresses the very common case of “getting a String out of a heterogeneous dictionary”.

let name = plist[“name”] as! String

becomes one of these:

let name = plist[“name”] as! NSString as String
let name = String(plist[“name”] as! NSString)
let name = String(forceBridging: plist[“name”]) // not in the proposal

none of which I’m particularly happy with.

Jordan

···

On May 19, 2016, at 02:31, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

  * What is your evaluation of the proposal?

The review is technically over, but I don't believe a decision has been announced yet, so...

I am generally in favor, but I have a serious concern about the readability of certain conversions with this change. To wit, conversions like these:

  myArray as! [NSView]
  myDictionary as! [String: NSView]

Are about to become something more like these:

  [NSView](forcedLazyBridging: myArray)
  [String: NSView](forcedLazyBridging: myDictionary)
  
Or these:

  Array<NSView>(forcedLazyBridging: myArray)
  Dictionary<String, NSView>(forcedLazyBridging: myDictionary)

Either option is a significant regression in code readability compared to the status quo.

It's enough to make me wonder if we shouldn't have special-cased conversion methods for NSArray, NSDictionary, and NSSet:

  myArray.of(NSView) // returns [NSView]
  myDictionary.of(NSView, for: String) // returns [String: NSView]
  mySet.of(NSView) // returns Set<NSView>

On the other hand, if you *don't* have to specify an element type, these aren't so bad:

  Array(forcedLazyBridging: myArray)
  Dictionary(forcedLazyBridging: myDictionary)

And it gets even better if you use something a little saner than `forcedLazyBridging` for the label.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Conversions are a mess, and it'll be nice to clean them up.

  * Does this proposal fit well with the feel and direction of Swift?

Yes.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Most languages I've used have had much simpler cast systems with nothing particularly close to Swift's bridging casts.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading.

--
Brent Royal-Gordon
Architechies

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


(Jed Lewison) #7

If we could have extensions on AnyObject, a simple .bridge() would do the trick, right? (Assuming bridge was generic.) I think something along those lines was mentioned in the proposal.

···

Sent from my iPhone

On May 23, 2016, at 5:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

I am way late, but I share Brent’s concerns. I don’t think this addresses the very common case of “getting a String out of a heterogeneous dictionary”.

let name = plist[“name”] as! String

becomes one of these:

let name = plist[“name”] as! NSString as String
let name = String(plist[“name”] as! NSString)
let name = String(forceBridging: plist[“name”]) // not in the proposal

none of which I’m particularly happy with.

Jordan

On May 19, 2016, at 02:31, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

  * What is your evaluation of the proposal?

The review is technically over, but I don't believe a decision has been announced yet, so...

I am generally in favor, but I have a serious concern about the readability of certain conversions with this change. To wit, conversions like these:

  myArray as! [NSView]
  myDictionary as! [String: NSView]

Are about to become something more like these:

  [NSView](forcedLazyBridging: myArray)
  [String: NSView](forcedLazyBridging: myDictionary)
  
Or these:

  Array<NSView>(forcedLazyBridging: myArray)
  Dictionary<String, NSView>(forcedLazyBridging: myDictionary)

Either option is a significant regression in code readability compared to the status quo.

It's enough to make me wonder if we shouldn't have special-cased conversion methods for NSArray, NSDictionary, and NSSet:

  myArray.of(NSView) // returns [NSView]
  myDictionary.of(NSView, for: String) // returns [String: NSView]
  mySet.of(NSView) // returns Set<NSView>

On the other hand, if you *don't* have to specify an element type, these aren't so bad:

  Array(forcedLazyBridging: myArray)
  Dictionary(forcedLazyBridging: myDictionary)

And it gets even better if you use something a little saner than `forcedLazyBridging` for the label.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Conversions are a mess, and it'll be nice to clean them up.

  * Does this proposal fit well with the feel and direction of Swift?

Yes.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Most languages I've used have had much simpler cast systems with nothing particularly close to Swift's bridging casts.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading.

--
Brent Royal-Gordon
Architechies

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

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


(Douglas Gregor) #8

I am way late, but I share Brent’s concerns. I don’t think this addresses the very common case of “getting a String out of a heterogeneous dictionary”.

let name = plist[“name”] as! String

becomes one of these:

let name = plist[“name”] as! NSString as String
let name = String(plist[“name”] as! NSString)
let name = String(forceBridging: plist[“name”]) // not in the proposal

none of which I’m particularly happy with.

I am also way, way late, here, but this ties into a philosophical concern I have. The bridging that we have in place was designed to put Swift’s value types front-and-center in the Swift experience, even when interoperating with Objective-C APIs using reference-semantic types. It was a specific goal that one should not have to juggle between Swift.Array and NSArray—NSArray is bridged away in imported APIs, Swift arrays implicitly convert to AnyObject when working an AnyObject-based API, dynamic bridging conversions would pass through NSArray to get to Swift arrays, etc. So while one can certainly reach for NS(Mutable)Array in Swift, one should not *have* to do so in Swift.

This proposal and SE-0072 are chipping away at that bridging story, making the explicit use of NSArray/NSString/etc. required for interoperability with Objective-C APIs. While it does make the language more explicit and predictable (and dynamic casting more efficient!), it makes the use of these bridged reference-semantic more prevalent, which may lead to more overall confusion about which set of types to use. There might even be a portability argument: the current scheme lets you gloss over Any vs. AnyObject (which is a current difference we see in ObjC Foundation vs. corelibs Foundation).

  - Doug

···

On May 23, 2016, at 5:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Jordan

On May 19, 2016, at 02:31, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

  * What is your evaluation of the proposal?

The review is technically over, but I don't believe a decision has been announced yet, so...

I am generally in favor, but I have a serious concern about the readability of certain conversions with this change. To wit, conversions like these:

  myArray as! [NSView]
  myDictionary as! [String: NSView]

Are about to become something more like these:

  [NSView](forcedLazyBridging: myArray)
  [String: NSView](forcedLazyBridging: myDictionary)
  
Or these:

  Array<NSView>(forcedLazyBridging: myArray)
  Dictionary<String, NSView>(forcedLazyBridging: myDictionary)

Either option is a significant regression in code readability compared to the status quo.

It's enough to make me wonder if we shouldn't have special-cased conversion methods for NSArray, NSDictionary, and NSSet:

  myArray.of(NSView) // returns [NSView]
  myDictionary.of(NSView, for: String) // returns [String: NSView]
  mySet.of(NSView) // returns Set<NSView>

On the other hand, if you *don't* have to specify an element type, these aren't so bad:

  Array(forcedLazyBridging: myArray)
  Dictionary(forcedLazyBridging: myDictionary)

And it gets even better if you use something a little saner than `forcedLazyBridging` for the label.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Conversions are a mess, and it'll be nice to clean them up.

  * Does this proposal fit well with the feel and direction of Swift?

Yes.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Most languages I've used have had much simpler cast systems with nothing particularly close to Swift's bridging casts.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Jordan Rose) #9

Let’s see…

let name = plist[“name”].bridge() as String

Not the worst, but definitely better than any of the alternatives below. Unfortunately, I think that “if” is out of the question, at least for Swift 3.

Jordan

···

On May 23, 2016, at 20:21, Jed Lewison <jed.lewison@icloud.com> wrote:

If we could have extensions on AnyObject, a simple .bridge() would do the trick, right? (Assuming bridge was generic.) I think something along those lines was mentioned in the proposal.

Sent from my iPhone

On May 23, 2016, at 5:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I am way late, but I share Brent’s concerns. I don’t think this addresses the very common case of “getting a String out of a heterogeneous dictionary”.

let name = plist[“name”] as! String

becomes one of these:

let name = plist[“name”] as! NSString as String
let name = String(plist[“name”] as! NSString)
let name = String(forceBridging: plist[“name”]) // not in the proposal

none of which I’m particularly happy with.

Jordan

On May 19, 2016, at 02:31, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

  * What is your evaluation of the proposal?

The review is technically over, but I don't believe a decision has been announced yet, so...

I am generally in favor, but I have a serious concern about the readability of certain conversions with this change. To wit, conversions like these:

  myArray as! [NSView]
  myDictionary as! [String: NSView]

Are about to become something more like these:

  [NSView](forcedLazyBridging: myArray)
  [String: NSView](forcedLazyBridging: myDictionary)
  
Or these:

  Array<NSView>(forcedLazyBridging: myArray)
  Dictionary<String, NSView>(forcedLazyBridging: myDictionary)

Either option is a significant regression in code readability compared to the status quo.

It's enough to make me wonder if we shouldn't have special-cased conversion methods for NSArray, NSDictionary, and NSSet:

  myArray.of(NSView) // returns [NSView]
  myDictionary.of(NSView, for: String) // returns [String: NSView]
  mySet.of(NSView) // returns Set<NSView>

On the other hand, if you *don't* have to specify an element type, these aren't so bad:

  Array(forcedLazyBridging: myArray)
  Dictionary(forcedLazyBridging: myDictionary)

And it gets even better if you use something a little saner than `forcedLazyBridging` for the label.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Conversions are a mess, and it'll be nice to clean them up.

  * Does this proposal fit well with the feel and direction of Swift?

Yes.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Most languages I've used have had much simpler cast systems with nothing particularly close to Swift's bridging casts.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Charlie Monroe) #10

Ditto. It's way too early to be doing this. This is something to be done when most major APIs are converted to Swift. This would make Swift hard to use for any interaction with JSON if you use NSJSONSerialization and pretty much with any NSDictionary...

···

On May 25, 2016, at 6:49 AM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On May 23, 2016, at 5:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I am way late, but I share Brent’s concerns. I don’t think this addresses the very common case of “getting a String out of a heterogeneous dictionary”.

let name = plist[“name”] as! String

becomes one of these:

let name = plist[“name”] as! NSString as String
let name = String(plist[“name”] as! NSString)
let name = String(forceBridging: plist[“name”]) // not in the proposal

none of which I’m particularly happy with.

I am also way, way late, here, but this ties into a philosophical concern I have. The bridging that we have in place was designed to put Swift’s value types front-and-center in the Swift experience, even when interoperating with Objective-C APIs using reference-semantic types. It was a specific goal that one should not have to juggle between Swift.Array and NSArray—NSArray is bridged away in imported APIs, Swift arrays implicitly convert to AnyObject when working an AnyObject-based API, dynamic bridging conversions would pass through NSArray to get to Swift arrays, etc. So while one can certainly reach for NS(Mutable)Array in Swift, one should not *have* to do so in Swift.

This proposal and SE-0072 are chipping away at that bridging story, making the explicit use of NSArray/NSString/etc. required for interoperability with Objective-C APIs. While it does make the language more explicit and predictable (and dynamic casting more efficient!), it makes the use of these bridged reference-semantic more prevalent, which may lead to more overall confusion about which set of types to use. There might even be a portability argument: the current scheme lets you gloss over Any vs. AnyObject (which is a current difference we see in ObjC Foundation vs. corelibs Foundation).

  - Doug

Jordan

On May 19, 2016, at 02:31, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

  * What is your evaluation of the proposal?

The review is technically over, but I don't believe a decision has been announced yet, so...

I am generally in favor, but I have a serious concern about the readability of certain conversions with this change. To wit, conversions like these:

  myArray as! [NSView]
  myDictionary as! [String: NSView]

Are about to become something more like these:

  [NSView](forcedLazyBridging: myArray)
  [String: NSView](forcedLazyBridging: myDictionary)
  
Or these:

  Array<NSView>(forcedLazyBridging: myArray)
  Dictionary<String, NSView>(forcedLazyBridging: myDictionary)

Either option is a significant regression in code readability compared to the status quo.

It's enough to make me wonder if we shouldn't have special-cased conversion methods for NSArray, NSDictionary, and NSSet:

  myArray.of(NSView) // returns [NSView]
  myDictionary.of(NSView, for: String) // returns [String: NSView]
  mySet.of(NSView) // returns Set<NSView>

On the other hand, if you *don't* have to specify an element type, these aren't so bad:

  Array(forcedLazyBridging: myArray)
  Dictionary(forcedLazyBridging: myDictionary)

And it gets even better if you use something a little saner than `forcedLazyBridging` for the label.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Conversions are a mess, and it'll be nice to clean them up.

  * Does this proposal fit well with the feel and direction of Swift?

Yes.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Most languages I've used have had much simpler cast systems with nothing particularly close to Swift's bridging casts.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Rod Brown) #11

Yes, I have to say Doug seems to be on the money with the concerns I hold with the current proposals about stripping out the "Objective-C Magic" in the bridge between Swift and Objective C.

There seems to be a strong push recently to rip out these APIs with clearly well meaning intent, but lack of consideration for the many APIs that this will make rather uncomfortable to use.

I think this request tends to gloss over the fact that a vast majority of Swift code is still written for iOS and OS X and utilizes the Objective-C APIs extensively. As Doug points out, we are chipping away very fast at the bridging simplicity that made Swift brilliant to use on Apple Platforms, and I don't think the gains begin to approach the losses from these changes.

While I agree strongly with the concept of wiping such bridges out where possible in concept, I am pragmatic that perhaps doing so is not in the best interests of Swift's usability in the short term at least. I think because we haven't experienced writing an Objective-C based app in Swift, we might be getting lost in the "concept" of stripping bridging, while missing the real world implications of such actions.

- Rod

···

On 25 May 2016, at 2:49 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On May 23, 2016, at 5:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

I am way late, but I share Brent’s concerns. I don’t think this addresses the very common case of “getting a String out of a heterogeneous dictionary”.

let name = plist[“name”] as! String

becomes one of these:

let name = plist[“name”] as! NSString as String
let name = String(plist[“name”] as! NSString)
let name = String(forceBridging: plist[“name”]) // not in the proposal

none of which I’m particularly happy with.

I am also way, way late, here, but this ties into a philosophical concern I have. The bridging that we have in place was designed to put Swift’s value types front-and-center in the Swift experience, even when interoperating with Objective-C APIs using reference-semantic types. It was a specific goal that one should not have to juggle between Swift.Array and NSArray—NSArray is bridged away in imported APIs, Swift arrays implicitly convert to AnyObject when working an AnyObject-based API, dynamic bridging conversions would pass through NSArray to get to Swift arrays, etc. So while one can certainly reach for NS(Mutable)Array in Swift, one should not *have* to do so in Swift.

This proposal and SE-0072 are chipping away at that bridging story, making the explicit use of NSArray/NSString/etc. required for interoperability with Objective-C APIs. While it does make the language more explicit and predictable (and dynamic casting more efficient!), it makes the use of these bridged reference-semantic more prevalent, which may lead to more overall confusion about which set of types to use. There might even be a portability argument: the current scheme lets you gloss over Any vs. AnyObject (which is a current difference we see in ObjC Foundation vs. corelibs Foundation).

  - Doug

Jordan

On May 19, 2016, at 02:31, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

  * What is your evaluation of the proposal?

The review is technically over, but I don't believe a decision has been announced yet, so...

I am generally in favor, but I have a serious concern about the readability of certain conversions with this change. To wit, conversions like these:

  myArray as! [NSView]
  myDictionary as! [String: NSView]

Are about to become something more like these:

  [NSView](forcedLazyBridging: myArray)
  [String: NSView](forcedLazyBridging: myDictionary)
  
Or these:

  Array<NSView>(forcedLazyBridging: myArray)
  Dictionary<String, NSView>(forcedLazyBridging: myDictionary)

Either option is a significant regression in code readability compared to the status quo.

It's enough to make me wonder if we shouldn't have special-cased conversion methods for NSArray, NSDictionary, and NSSet:

  myArray.of(NSView) // returns [NSView]
  myDictionary.of(NSView, for: String) // returns [String: NSView]
  mySet.of(NSView) // returns Set<NSView>

On the other hand, if you *don't* have to specify an element type, these aren't so bad:

  Array(forcedLazyBridging: myArray)
  Dictionary(forcedLazyBridging: myDictionary)

And it gets even better if you use something a little saner than `forcedLazyBridging` for the label.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Conversions are a mess, and it'll be nice to clean them up.

  * Does this proposal fit well with the feel and direction of Swift?

Yes.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Most languages I've used have had much simpler cast systems with nothing particularly close to Swift's bridging casts.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading.

--
Brent Royal-Gordon
Architechies

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

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

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


(Jed Lewison) #12

The proposal also suggests:

extension _ObjectiveCBridgeable {
    init?(bridging object: AnyObject)
}

Which would yield:

let foo: AnyObject = NSString(string: "String")
let bar = String(bridging: foo) // “String"

let foo2: AnyObject = NSArray(array: [])
let bar2 = String(bridging: foo) // nil

The code in the proposal works OOB in Swift 2.2 for String/Double/Float, but not Array and Dictionary. Not sure if it already would work in Swift 3.0 for that, or there would need to be a little more work done.

···

On May 23, 2016, at 8:22 PM, Jordan Rose <jordan_rose@apple.com> wrote:

Let’s see…

let name = plist[“name”].bridge() as String

Not the worst, but definitely better than any of the alternatives below. Unfortunately, I think that “if” is out of the question, at least for Swift 3.

Jordan

On May 23, 2016, at 20:21, Jed Lewison <jed.lewison@icloud.com <mailto:jed.lewison@icloud.com>> wrote:

If we could have extensions on AnyObject, a simple .bridge() would do the trick, right? (Assuming bridge was generic.) I think something along those lines was mentioned in the proposal.

Sent from my iPhone

On May 23, 2016, at 5:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I am way late, but I share Brent’s concerns. I don’t think this addresses the very common case of “getting a String out of a heterogeneous dictionary”.

let name = plist[“name”] as! String

becomes one of these:

let name = plist[“name”] as! NSString as String
let name = String(plist[“name”] as! NSString)
let name = String(forceBridging: plist[“name”]) // not in the proposal

none of which I’m particularly happy with.

Jordan

On May 19, 2016, at 02:31, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

  * What is your evaluation of the proposal?

The review is technically over, but I don't believe a decision has been announced yet, so...

I am generally in favor, but I have a serious concern about the readability of certain conversions with this change. To wit, conversions like these:

  myArray as! [NSView]
  myDictionary as! [String: NSView]

Are about to become something more like these:

  [NSView](forcedLazyBridging: myArray)
  [String: NSView](forcedLazyBridging: myDictionary)
  
Or these:

  Array<NSView>(forcedLazyBridging: myArray)
  Dictionary<String, NSView>(forcedLazyBridging: myDictionary)

Either option is a significant regression in code readability compared to the status quo.

It's enough to make me wonder if we shouldn't have special-cased conversion methods for NSArray, NSDictionary, and NSSet:

  myArray.of(NSView) // returns [NSView]
  myDictionary.of(NSView, for: String) // returns [String: NSView]
  mySet.of(NSView) // returns Set<NSView>

On the other hand, if you *don't* have to specify an element type, these aren't so bad:

  Array(forcedLazyBridging: myArray)
  Dictionary(forcedLazyBridging: myDictionary)

And it gets even better if you use something a little saner than `forcedLazyBridging` for the label.

  * Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Conversions are a mess, and it'll be nice to clean them up.

  * Does this proposal fit well with the feel and direction of Swift?

Yes.

  * If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Most languages I've used have had much simpler cast systems with nothing particularly close to Swift's bridging casts.

  * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution