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. 

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

Reply via email to