Tuesday, March 2, 2021

Be Careful With Obj-C Bridging in Swift

Bruno Rocha:

While visually the same, this case is completely different from the view controllers one! String does not inherit or uses NSString in any way -- they are different objects with different implementations. The way this works is that as in this case is a syntax sugar for the following[…]


Cases like this can be extremely confusing if your Swift method cannot predict where its arguments are coming from, because as we can see above, the very same object can completely change the result of an operation depending on if it was bridged or not. If it wasn’t enough, things get even worse when you deal with the fact that the very same method can have different implementations across languages[…]


I personally think that using as as a syntax sugar for bridging was not the best idea.

What it does is fine, but perhaps it should have been spelled differently.


Update (2021-03-22): SE-0083 (deferred):

Dynamic casts using as?, as!, and is are currently able to dynamically perform Cocoa bridging conversions, such as from String to NSString or from an ErrorProtocol-conforming type to NSError. This functionality should be removed to make dynamic cast behavior simpler, more efficient, and easier to understand. To replace this functionality, initializers should be added to bridged types, providing an interface for these conversions that’s more consistent with the conventions of the standard library.

4 Comments RSS · Twitter


While not perfect, it is still better than the Swift 2 behaviour, which was to also implicit cast IIRC.

This is, of course, completely missing the forest for the trees: Swift is a bad Cocoa programming language. It might someday become a good Swift[UI] programming language, but the ROI for 15-20 years of tossing a mature 30-year ecosystem in trade for some personal CV glory will always be dismal.

The least-bad thing Apple can do at this point is to stop wasting time on mistakes of the past and accelerate the transition to a 100% pure Swift ecosystem, at which point all these problems cease to exist. Stay-and-play is an exercise in circular sailing. All it does is drop an anchor behind change, and with it goes forward progress.

Compare the Python 2-to-3 fiasco: a decade of progress squandered, reams of worthless code being written to please the compiler instead of doing useful work, incoherent messaging as to why the world should want to use Python over anything else. That Perl-esque odor of a stalled-out, fading platform; not good. All because no-one in charge could decide if users should be writing Python2 code that can upgrade to 3, or Python3 code that can downgrade to 2, or twisting it wretched nonsense that tries to run on both.†

That’s the trap Swift still dallies with, and while it’s done a better job of forward migrating itself that’s the least users should expect nowadays. Swift’s impedance mismatch with the ObjC world is hardcoded into its bones. ObjC libraries should’ve been skimmed over as quickly as possible with ObjC++ shims, so the guts could be pulled out and replaced at leisure. But, having failed that, the goal now should be to get everyone off them as quick as poss. A pure Swift world won’t be great, but at least it’ll be coherent; and then maybe at last we’ll see productive progress start.

(It should also go without saying that the core language developers dicking with the core language seriously needs to stop; and really should’ve stopped several years ago. I get it: APIs are drudgework without the glory, but the bloody work needs done.)


† Correct answer: Get everyone to write and maintain ALL code as 100% Python 3 ASAP, and provide fully automated 3-to-2 transpiling until everyone’s code can run directly on 3 as well. (Rationale: the new language can have full knowledge of its predecessor and be crafted to provide fully automated 3-to-2 conversions. Whereas the old language is full of bad features and ambiguity, meaning 2-to-3 conversion can only be semi-automated with manual inteventions. Besides, if Py2 could evolve upwards it wouldn’t have needed replacing in the first place.) Contrast TypeScript (which admittedly is a ballache to compile down to ES3 thanks to it making you do all the polyfilling yourself) but at least it does it once all set up. 20 years’ cross-compilation; that’s not bad.

"reams of worthless code being written to please the compiler instead of doing useful work"

So, pretty much like 90% of every programming language?

Old Unix Geek

The least-bad thing Apple can do at this point is to stop wasting time on mistakes of the past and accelerate the transition to a 100% pure Swift ecosystem

Least bad? Return to Objective-C.

Leave a Comment