Upon Swift 6: Solve inconsistency within the language

One thing I’d like to see relaxed in Swift 6 is Objective-C bridging.

Currently, Swift allows NSString methods to be called on String instances. However, these functions often have better alternatives that are native to Swift:

let foo = "hello ".appending("world")
// use of `+=` or `+` is preferred

And many of these NSString methods aren’t Unicode-correct (instead operating on UTF-16 code units), which is unexpected behavior to many people as native String methods are Unicode-correct.

let bar = "👨‍👩‍👧‍👦".padding(toLength: 14, withPad: "0", startingAt: 0)
// 👨‍👩‍👧‍👦000
let baz = "👨‍👩‍👧‍👦".padding(toLength: 10, withPad: "0", startingAt: 0)
// 👨‍👩‍👧‍�

And these methods return bridged NSStrings instead of native strings, which can be unexpected since there is no indication that they will return a bridged NSString.

Despite this inconsistency and its associated confusion, people still recommend the use of these functions over their Swift equivalents. If you search for “how to pad a string in swift” in Google, every search result tells you to use NSString.padding. (At least, it does for me — Google is known to have a “filter bubble” that changes search results based on the information it collects from you.)

In addition, I think that Swift is mature enough now that we should stop relying on C / Objective-C interoperability behavior for simple things like this. We should remove these kinds of “bridged” methods from native Swift types. If a programmer really wants to use these methods, we should require them to cast the Swift type to the Objective-C equivalent like so:

let hello = "hello "
let helloWorld = (hello as NSString).appending("world")

There should also be a warning in the NSString documentation that most of its methods operate on UTF-16 code units and do not have Unicode-correct behavior.


I’d also like to see some of the Foundation types be re-renamed back to their Objective-C names. Types like NumberFormatter and Timer look like Swift types, but act like Objective-C classes in a way that’s inconsistent with the rest of the language. Also, NumberFormatter now has a native Swift equivalent and Timer has a Combine equivalent. Having two native-looking APIs for the same thing is confusing and should be avoided.

The renaming of these types happened a long time ago (relatively), back when Swift was still dependent on Objective-C for doing almost anything. Now, Swift is more independent, with its own APIs and its own style, and Foundation should reflect that.

15 Likes