Structural opaque result types

It's great!

But I doubt this point.

[Edit]
I've misread. This is only an example which closure with opaque result type argument can be called.

IIUC, your argument is that, there is no way to call g, and therefore should be explicitly disallowed. But it's not true. I previously posted about 'reverse generic argument types'. Consider following closure:

var closure: (some Numeric) -> () = { (value: Double) in print(value) }

some Numeric is actually Double, but it doesn't matter. We have information about some Numeric: it conforms to ExpressibleByIntegerLiteral and it has static property zero. Therefore, even though we cannot call this closure with Double, we can still use this closure like this:

closure(42)       // 42
closure(21)       // 21
closure(.zero)    // 0

Actually similar behavior has been in the current Swift already. You can try how it works:

protocol Printer {
    func print(value: Self)
}
extension Double: Printer {
    func print(value: Double) { Swift.print(value) }
}
let d: some (Numeric & Printer) = 42.0
let closure = d.print
// you can still call this closure!
closure(42.0)    // error (since type is opaque)
closure(42)      // OK (from ExpressibleByIntegerLiteral)
closure(.zero)   // OK (from AdditiveArithmetic)

Like this, having g doesn't cause any problems. You can still call the closure, and use it. There is no reason to explicitly disallow it.

7 Likes