Feature Request: A way to do a kinda half-way typealias

(This is part of my larger desire for Swift to have explicit code-generation support, since we don't get macros anymore)


For instance, say I've defined a Point type:

struct Point2D<T: ScalarType> : CustomStringConvertible, Equatable {
//Yes, I know there's no such protocol as "ScalarType". Hint, hint... nudge, nudge...
     var x: T
     var y: T
     var description: String {
          return "(\(x), \(y))"
     }
}
func == <T: ScalarType> (lhs: Point2D<T>, rhs:Point2D<T>)-> Bool {
     return lhs.x == rhs.x && lhs.y == rhs.y
}

and I want a Vector2D type. The easiest way would be a typealias:

typealias Vector2D = Point2D<Double>

But then when I write the dot product function

func * (lhs: Vector2D, rhs: Vector2D) -> Double {
     return lhs.x * rhs.x + lhs.y * rhs.y
}

... code like

let v = Vector2D(x: 3.0, y: 1.2)
let p = Point2D(x: 1.0, y: 1.3)
let foo = v * p

... will compile even though, at least semantically speaking, it breaks Swift's type-safety.

Obviously, this is a pretty trivial example, but in the general sense it allows one more form of code reuse, and it seems like it'd be easier (and probably safer) to only have one "template type" to edit if I wanted to add support for using SIMD instructions in the addition function, for example (which would be identical in both Points and Vector2Ds, in this example).

What are the chances that the next version of Swift could have a "specialize" keyword or something? The way it conceptually works (in my head, at least) the "specialize" keyword could almost* simply be a macro that replaces "specialize Vector2D: OnePointToRuleThemAll<CGFloat> with the contents of "OnePointToRuleThemAll.swift", replaces instances of "OnePointToRuleThemAll" with "CGPoint", replaces instances of "T" with "CGFloat", and appends anything in the {} to the new definition (putting it in an implicit extension might be the easiest way):

specialize Vector2D: Point2D<Double> {
     var length: Double {
          return sqrt(x*x + y*y)
     }
}

This way, you can't use a Point2D where your code is expecting a Vector2D, and you don't give Point2Ds extra properties or methods that are only meant for Vector2Ds.


*I say "almost" because this copy/paste scenario assumes you have access to the source code in which the original type was defined. Since that's not necessarily the case, in practice it'd have to be a bit different.


Syntactically speaking, I think the same thing could be done by adding two other features (both of which would come in handy from time to time anyway): a mechanism for classes to have value semantics (or structs to have, um, "substructs"), and a way to tell the compiler to sorta "forget" a subtype's relationship to its parent type during the type-checking phase. I'm not sure which is a better approach.

Replies

Feel free to use Report Bugs, bottom right, to initiate feature requests.