[swift-evolution] Pitch: really_is and really_as operators

Callionica (Swift) swift-callionica at callionica.com
Wed Aug 24 20:28:37 CDT 2016


I used this several months ago for extracting data from Any:

// Dynamic cast without bridging
func dynamicCast<T>(_ type: T.Type, _ v: Any)->T? {
    guard let result = v as? T where v.dynamicType is T.Type else {
        return nil;
    }
    return result
}

from http://www.callionica.com/developer/#any-equals

based on suggestion from Joe Groff


On Wed, Aug 24, 2016 at 6:11 PM, Jaden Geller via swift-evolution <
swift-evolution at swift.org> wrote:

> Though this performs an *extra* check over just `x as! U`, it avoids
> bridging conversions. I don't think this extra check matters though because
> you wouldn't be using `Any` in code that's performance critical enough for
> this to matter, so I'm currently -1 on this proposal.
>
> On Aug 24, 2016, at 6:09 PM, Jaden Geller <jaden.geller at gmail.com> wrote:
>
> Scratch that last message. Determining what's stored in `Any` was
> Charles's original goal, and what I said made no sense. This should work:
>
> func unbridgedCast<T, U>(_ x: T, to: U.Type) -> U? {
>     guard type(of: x) is U.Type else { return nil }
>     return x as! U
> }
>
> if let x = unbridgedCast(x, to: String.self) { ... }
>
> On Aug 24, 2016, at 6:06 PM, Jaden Geller <jaden.geller at gmail.com> wrote:
>
> Actually, the code I proposed does not work. First of all, it doesn't work
> for subtype relations. This can easily be fixed though by changing `==
> U.self` to `is U`. More importantly though, it fails when `T` is an
> existential since `type(of:)` looks within the existential to determine the
> type. It would be useful if there were a way to determine the *actual*
> runtime representation of the value.
>
> On Aug 24, 2016, at 6:00 PM, Jaden Geller <jaden.geller at gmail.com> wrote:
>
> Taking that suggestion a step further, it's pretty easy to define a
> function that performs this sort of casting without bridging.
>
> func unbridgedCast<T, U>(_ x: T, to: U.Type) -> U? {
>     guard type(of: x) == U.self else { return nil }
>     return unsafeBitCast(x, to: U.self)
> }
>
> On Aug 24, 2016, at 5:42 PM, Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> import Foundation
>
> let foo: Any = "Hello"
> type(of: foo) == String.self // true
> type(of: foo) == NSString.self // false
>
> let bar: Any = "Hello" as NSString
> type(of: bar) == String.self // false
> type(of: bar) == NSString.self // true
>
> Why not this?
>
>
> On Wed, Aug 24, 2016 at 19:09 Charles Srstka via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> MOTIVATION:
>>
>> SE-0083 appears to be dead in the water, having been deferred until later
>> in Swift 3 back in May and not having been heard from since then, with the
>> Swift 3 release looming closer and closer. However, the predictability
>> gains that would have been provided by this change remain desirable for
>> cases where one needs to know the actual dynamic type of an entity before
>> any bridging magic is involved. Additionally, performance-critical code may
>> desire the ability to check something’s type quickly without incurring the
>> overhead of Objective-C bridging code.
>>
>> PROPOSED SOLUTION:
>>
>> I propose the following operators: really_is, really_as, really_as?, and
>> really_as!. These operators would only return a positive result if the type
>> actually was what was being asked for, instead of something that might be
>> able to bridge to that type.
>>
>> DETAILED DESIGN:
>>
>> let foo: Any = "Foo"
>> let bar: Any = NSString(string: "Bar")
>>
>> let fooIsString = foo is String                  // true
>> let fooReallyIsString = foo really_is String     // true
>>
>> let fooIsNSString = foo is NSString              // true
>> let fooReallyIsNSString = foo really_is NSString // false
>>
>> let barIsString = bar is String                  // true
>> let barReallyIsString = bar really_is String     // false
>>
>> let barIsNSString = bar is NSString              // true
>> let barReallyIsNSString = bar really_is NSString // true
>>
>> ALTERNATIVES CONSIDERED:
>>
>> Stick with using an unholy combination of Mirror and unsafeBitCast when
>> you need to know what you’ve actually got.
>>
>> Charles
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160824/799a8297/attachment.html>


More information about the swift-evolution mailing list