[Accepted] SE-0072: Fully eliminate implicit bridging conversions from Swift


(Chris Lattner) #1

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md

Hello Swift Community,

The review of SE-0072 "Fully eliminate implicit bridging conversions from Swift” ran from April 26 ... May 2, 2016. The proposal is *accepted* for Swift 3.

The feedback on this proposal was positive - the benefits of simplifying the type system and eliminating surprising behavior from the compiler is universally appealing. However, both the core team and the community wanted a better sense of what the impact of the proposal would be in practice on real code. Joe Pamer did some analysis and found out that there isn’t a significant impact on the most concerning use case:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016644.html

Thank you to Joe Pamer for driving the proposal and the implementation work for this improvement!

-Chris
Review Manager


(Jacob Bandes-Storch) #2

Does this affect the ability to use "x as? Int" (and similar) when x is an
NSNumber?

Jacob

···

On Thu, May 5, 2016 at 9:50 PM, Chris Lattner via swift-evolution < swift-evolution@swift.org> wrote:

Proposal link:
https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md

Hello Swift Community,

The review of SE-0072 "Fully eliminate implicit bridging conversions from
Swift” ran from April 26 ... May 2, 2016. The proposal is *accepted* for
Swift 3.

The feedback on this proposal was positive - the benefits of simplifying
the type system and eliminating surprising behavior from the compiler is
universally appealing. However, both the core team and the community
wanted a better sense of what the impact of the proposal would be in
practice on real code. Joe Pamer did some analysis and found out that
there isn’t a significant impact on the most concerning use case:

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016644.html

Thank you to Joe Pamer for driving the proposal and the implementation
work for this improvement!

-Chris
Review Manager

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


(Joe Groff) #3

No, this only affects compile-time implicit conversions. I proposed changing the runtime behavior of dynamic casts in SE-0083:

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

-Joe

···

On May 6, 2016, at 12:21 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

Does this affect the ability to use "x as? Int" (and similar) when x is an NSNumber?


(Charles Srstka) #4

I’d just like to throw in that the ability to use “x as? Int” when x is an NSNumber is terrible.

let num: AnyObject = NSNumber(int: 5)

let int = num as? Int // 5
let float = num as? Float // 5
let int32 = num as? Int32 // nil!

Completely unexpected failure, and you’ll never know about it until runtime.

Charles

···

On May 6, 2016, at 3:15 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On May 6, 2016, at 12:21 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Does this affect the ability to use "x as? Int" (and similar) when x is an NSNumber?

No, this only affects compile-time implicit conversions. I proposed changing the runtime behavior of dynamic casts in SE-0083:

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


(Jacob Bandes-Storch) #5

Agreed, but I'm sure lots of user code depends on it (e.g. when extracting
numeric values from property lists). If it stopped working, wouldn't these
"as?" casts silently start returning nil where they didn't before?

···

On Fri, May 6, 2016 at 8:20 PM Charles Srstka <cocoadev@charlessoft.com> wrote:

On May 6, 2016, at 3:15 PM, Joe Groff via swift-evolution < > swift-evolution@swift.org> wrote:

On May 6, 2016, at 12:21 PM, Jacob Bandes-Storch via swift-evolution < > swift-evolution@swift.org> wrote:

Does this affect the ability to use "x as? Int" (and similar) when x is an
NSNumber?

No, this only affects compile-time implicit conversions. I proposed
changing the runtime behavior of dynamic casts in SE-0083:

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

I’d just like to throw in that the ability to use “x as? Int” when x is an
NSNumber is terrible.

let num: AnyObject = NSNumber(int: 5)

let int = num as? Int // 5
let float = num as? Float // 5
let int32 = num as? Int32 // nil!

Completely unexpected failure, and you’ll never know about it until
runtime.

Charles


(Zachary Waldowski) #6

That specific behavior with Int32 seems to be an oversight in the
stdlib. The specific integer types don't get an ObjectiveCBridgeable
implementation.

Sincerely,
Zachary Waldowski
zach@waldowski.me

···

On Fri, May 6, 2016, at 11:20 PM, Charles Srstka via swift-evolution wrote:

let int = num as? Int // 5
let float = num as? Float // 5
let int32 = num as? Int32 // nil!


(Joe Groff) #7

My pitch to eliminate this casting behavior got pulled as SE-0083, up for review this week:

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

-Joe

···

On May 6, 2016, at 8:20 PM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On May 6, 2016, at 3:15 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On May 6, 2016, at 12:21 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

Does this affect the ability to use "x as? Int" (and similar) when x is an NSNumber?

No, this only affects compile-time implicit conversions. I proposed changing the runtime behavior of dynamic casts in SE-0083:

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

I’d just like to throw in that the ability to use “x as? Int” when x is an NSNumber is terrible.

let num: AnyObject = NSNumber(int: 5)

let int = num as? Int // 5
let float = num as? Float // 5
let int32 = num as? Int32 // nil!

Completely unexpected failure, and you’ll never know about it until runtime.


(Charles Srstka) #8

On the downside: This is absolutely true. All of those conversions would be the first up against the well when the revolution comes.

On the upside: I imagine a compiler warning could be pretty reasonably whipped up to detect these, and after the dust cleared, we’d be able to just try Int32(foo) and either the initializer would exist, or it wouldn’t, and it wouldn’t be necessary to bust out a playground and test to see if it’ll actually work every time you want to cast something to a number type that’s not your basic Int or Float.

Charles

···

On May 6, 2016, at 11:01 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Agreed, but I'm sure lots of user code depends on it (e.g. when extracting numeric values from property lists). If it stopped working, wouldn't these "as?" casts silently start returning nil where they didn't before?


(Joe Groff) #9

It wasn't an oversight. At the time of Swift 1.0, bridging a type implied bidirectional implicit conversions, and if *every* integer type were bridgeable, it would be possible to unsafely implicitly convert between any two integer types by hopping through NSNumber. Now that we've eliminated these implicit conversions, we could consider bridging more types. Do you want to start another thread to discuss that idea?

-Joe

···

On May 7, 2016, at 1:23 PM, Zach Waldowski via swift-evolution <swift-evolution@swift.org> wrote:

On Fri, May 6, 2016, at 11:20 PM, Charles Srstka via swift-evolution wrote:

let int = num as? Int // 5
let float = num as? Float // 5
let int32 = num as? Int32 // nil!

That specific behavior with Int32 seems to be an oversight in the stdlib.


(Jacob Bandes-Storch) #10

Maybe I made a mistake when testing, but I thought I was able to convert a
negative Int to a large UInt by going through NSNumber (it didn't return
nil from the as? cast).

···

On Mon, May 9, 2016 at 10:11 AM Joe Groff via swift-evolution < swift-evolution@swift.org> wrote:

> On May 7, 2016, at 1:23 PM, Zach Waldowski via swift-evolution < > swift-evolution@swift.org> wrote:
>
> On Fri, May 6, 2016, at 11:20 PM, Charles Srstka via swift-evolution > wrote:
>> let int = num as? Int // 5
>> let float = num as? Float // 5
>> let int32 = num as? Int32 // nil!
> That specific behavior with Int32 seems to be an oversight in the stdlib.

It wasn't an oversight. At the time of Swift 1.0, bridging a type implied
bidirectional implicit conversions, and if *every* integer type were
bridgeable, it would be possible to unsafely implicitly convert between any
two integer types by hopping through NSNumber. Now that we've eliminated
these implicit conversions, we could consider bridging more types. Do you
want to start another thread to discuss that idea?

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


(Joe Groff) #11

It's less bad if you're able to do this explicitly. It was the *implicit* conversion behavior we were concerned about.

-Joe

···

On May 9, 2016, at 10:12 AM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Maybe I made a mistake when testing, but I thought I was able to convert a negative Int to a large UInt by going through NSNumber (it didn't return nil from the as? cast).