> 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
