[swift-evolution] SE-0005: Ambiguous NS prefix removals

Brent Royal-Gordon brent at architechies.com
Fri Dec 4 05:50:39 CST 2015

SE-0005 in the repository (“Better Translation of Objective-C APIs into Swift”, https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md) discusses plans to remove the NS prefix from many Foundation APIs, but admits that you haven’t yet settled on a way to handle conflicts with the standard library:

> The removal of the "NS" prefix for the Foundation module (or other specifically identified modules) is a mechanical translation for all global symbols defined within that module that can be performed in the Clang importer. Note that this removal can create conflicts with the standard library. For example, NSString and NSArray will become String and Array, respectively, and Foundation's versions will shadow the standard library's versions. We are investigating several ways to address this problem, including:
> 	• Retain the NS prefix on such classes.
> 	• Introduce some notion of submodules into Swift, so that these classes would exist in a submodule for reference-semantic types (e.g., one would refer to Foundation.ReferenceTypes.Array or similar).

Since the main difference between e.g. String and NSString is that the latter has reference semantics, why not alter the name to reflect that?

	NSString -> StringRef
	NSArray -> ArrayRef
	NSDictionary -> DictionaryRef

The resulting type names have a bit of a Core Foundation-y flavor to them, but that’s not necessarily a bad thing—it quietly encourages use of the Swift types just as NSString vs. CFStringRef quietly encourages use of the Foundation type.

Normally this transformation would not apply to types with no corresponding standard library type:

	NSCalendar -> Calendar
	NSBundle -> Bundle

However, subclasses of a type with “Ref” in the name would also have “Ref" in the subclass name:

	NSMutableString -> MutableStringRef (because its superclass is StringRef)
	NSMutableArray -> MutableArrayRef (because its superclass is ArrayRef)
	NSMutableDictionary -> MutableDictionaryRef (because its superclass is DictionaryRef)

If you don’t like “Ref”, “Object” is wordier but clearer:

	StringObject, MutableStringObject
	ArrayObject, MutableArrayObject
	DictionaryObject, MutableDictionaryObject

And as long as we’re doing this, it might make sense to add the “Ref” suffix for a few other types which might naturally have value-typed standard library equivalents someday, even if they don’t right now:

	URLRef (the URL type would have something like NSURLComponents’s mutation APIs)
	DateComponentsRef (this is begging to be a struct in Swift)
	DateRef (perhaps less important, since it’s immutable and doesn’t really have many natural properties to expose anyway)
	NumberRef (a standard library equivalent might be a protocol that all numeric types conform to)

On the other hand, you might just want to cross that bridge when you get to it with a source code migrator in Swift 4 or whatever.

(By the way, I love the rest of this proposal. I’ve always wanted Swift to clean up and reformat API names more when it imports them.)

Brent Royal-Gordon

More information about the swift-evolution mailing list