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

Brent Royal-Gordon brent at architechies.com
Fri Dec 4 14:09:37 CST 2015

> 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.

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?

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

More information about the swift-evolution mailing list