[swift-evolution] SE-0005: Ambiguous NS prefix removals
anthony.parker at apple.com
Fri Dec 4 13:12:37 CST 2015
> On Dec 4, 2015, at 3:50 AM, Brent Royal-Gordon <brent at architechies.com> wrote:
> 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.
We’ve been thinking about exactly what to call this submodule, but haven’t landed on a preferred name yet. For the class names themselves, I don’t think we want to suffix some classes with ‘Ref’ or ‘Object’ but not others, because it would lead to either boilerplate names or inconsistency. The idea of the submodule was to avoid the inconsistency but still have something which obviously separates these classes.
NSString -> submodule.String
NSBundle -> Bundle
NSMutableString -> submodule.MutableString
NSArray -> submodule.Array
> (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
> swift-evolution mailing list
> swift-evolution at swift.org
More information about the swift-evolution