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

Tony Parker anthony.parker at apple.com
Fri Dec 4 14:45:10 CST 2015

> On Dec 4, 2015, at 12:09 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
>> 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.
> But I’m not sure using a submodule really solves either of these problems.
> BOILERPLATE: How are you going to address types inside the module? Either you’ll have to always include the prefix—in which case the prefix is boilerplate, but it’s in the wrong place on the type name to read correctly (“reference array” instead of “array reference”) and requires an extra character due to the “.”—or there will be some way to make Swift favor the reference types over the value types, in which case you won’t even be able to read “Array” or “String” in a piece of code without wondering which semantics you’re talking about.

You’re right that there is going to be some boilerplate here. Inside the Foundation module we’re willing to accept the readability hit of using submodule.Array when we mean “NSArray.” Using NSArray outside of Foundation itself should be relatively rare compared to using the standard library Array, so it should not be very prevalent there.

The idea we’ve been thinking about is to add something (in the module map, or in the class interface itself) here which makes the submodule specification required. We don’t have that capability today, so we need a compiler change of some kind to make this work if it is the direction we go. That means that Array always means Array.

> INCONSISTENCY: Not every type in Foundation will be moved into this submodule; some will stay behind in the top-level Foundation module. Doesn’t that mean the submodule approach is inconsistent too?

It would just be for types which have a value type equivalent in Swift that we would rather be used in most situations. This is why NSString Obj-C API is imported into Swift API as String, for example.

> So is putting these types into a submodule actually fixing these problems, or is it just sticking a dot after them?
> Actually, as long as we’re here, here’s a weird idea I just came up with. Why not nest the reference types inside the types they bridge to?
> 	NSString -> String.Reference
> 	NSMutableString -> String.MutableReference
> 	NSArray<T> -> Array<T>.Reference
> 	NSMutableArray<T> -> Array<T>.MutableReference
> This would require you to get a handle on nesting types within generic types, but personally, that’s always been a pain point for me in Swift’s design. With the right type resolution rules, it might also allow you to say something like this and let Swift figure out what you mean:
> 	let foo = “foo bar baz” as .Reference	// implicitly means String.Reference
> And if this was driven by a protocol with a typealias for the reference type, you could even make this public so users who have their own matching value/reference types can have them autoboxed:
> 	// Think of this as a cleaned up version of _ObjectiveCBridgeable.
> 	public protocol Referable {
> 		typealias Reference: class
> 		static func referenceType() -> Reference.Type			// or make it possible to get this from the protocol witness
> 		var reference: Reference { get }
> 		init?(reference: Reference)							// for an as! conversion, this is force-unwrapped by the caller
> 	}
> -- 
> Brent Royal-Gordon
> Architechies

This is an interesting idea; although I think it goes beyond what we had in mind for just the renaming. Even without the casting idea you propose, the names are not too different from calling the submodule ‘Reference’, which is something we considered:

NSString -> Reference.String
NSMutableString -> Reference.MutableString
NSArray -> Reference.Array

etc. The problem with this in my mind is that ‘Reference’ is not a good enough word to describe the difference between Foundation.NSString and Swift.String.

- Tony

More information about the swift-evolution mailing list