> On Dec 5, 2016, at 11:46 PM, Zach Waldowski via swift-evolution 
> <[email protected]> wrote:
> 
> I hate to be a thread necromancer, but I ran into the limits of the current 
> behavior several times today alone. I was perhaps overexcited by the 
> additional ObjectiveCBridgeable compliance of numeric types, and took off 
> several `.rawValue`s in a way that were hard to track down.
> 
> A few other examples, similar to what came up in the original thread:
> 
> 1. An options dictionary.
> 
> ```
> let detectedEncoding = NSString.stringEncoding(for: content, encodingOptions: 
> [
>    .suggestedEncodingsKey: [ String.Encoding.utf8 ]
> ], convertedString: nil, usedLossyConversion: nil)
> ```
> 
> This syntax looks surprisingly Swifty, but fails at runtime. id-as-Any means 
> a new developer can go a long way without knowing many types even /are/ 
> RawRepresentable.
> 
> 2. KVC. Given a newtype wrapper, I can have:
> 
> ```
> class StrawMan: NSObject {
>    dynamic var lookMa: Notification.Name?
> }
> 
> var demo: StrawMan = …
> demo.lookMa = .noStrings
> ````
> 
> But I can’t do:
> 
> ```
> demo.setValue(Notification.Name.noStrings, forKey: #keyPath(StrawMan.lookMa))
> ```
> 
> Worse, again, this only fails at runtime, rather than at compile time.
> 
> 3. Generics, similar in scope to #2.
> 
> ```
> class ValueTransformer<In, Out>: Foundation.ValueTransformer {
>    // use your imagination, id-as-Any is involved
> }
> 
> @objc enum TestEnum: Int { case one, two, three }
> 
> let t = ValueTransformer<Int, TestEnum>(…) // mysteriously fails because a 
> TestEnum crosses Any as _SwiftValue
> ```
> 
> Like I say above, armed with the vague recollection of my proselytizing about 
> id-as-Any, especially the extent to how well stuff like NSNull bridging 
> works, a team member could easily make mistakes that aren’t caught until 
> runtime. Between example #2 and #3 I consider the behavior today to be 
> approaching bug territory because of its big breakage of the principle of 
> least surprise.
> 
> Though I’m sympathetic with the fears from the original thread(s) about 
> making the bridge too fuzzy, I think being @objc, conforming to 
> RawRepresentable, and the RawValue conforming to ObjectiveCBridgeable is more 
> than enough information to go on (without treading into territory of 
> purposefully misusing RawRepresentable). RawRepresentable requires a failable 
> initializer, and I expect a well-behaved initializer to tie in with casting 
> of the RawValue to make an overall “as?” cast work as expected, fuzziness be 
> damned.
> 
> In basically every case I can think of involving the Cocoa bridge, bridging 
> using the RawValue is the right behavior. In most cases not considering the 
> Cocoa bridge, a predictable set of rules combined with an explicit “as?” Cast 
> is more than explicit enough to justify whatever behavior the compiler comes 
> up with.
> 
> Overall, It makes me more than uneasy to use a compiler feature about which 
> the most confidence I can get is reading the stdlib/overlay sources to find 
> out what secret conformances are declared. 

Given that we already bridge imported types with the "swift_newtype" attribute, 
it seems reasonable to me to do so for imported NS_ENUM/NS_OPTIONS types too, 
and perhaps as magic for @objc enums too. In all these cases, the bridging is 
introduced at the point of declaration of the type, so there isn't the concern 
about types becoming post-hoc bridgable by extensions that you'd have by making 
RawRepresentable imply bridging.

-Joe
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to