Help with Generic Type Aliases

Trying the following example from 0048 (Generic Type Aliases)

typealias BackwardTriple <T1,T2,T3> = (T3, T2, T1)
// Does this really work?
//
typealias BackwardTriple <T1,T2,T3> = (T3, T2, T1)

let u = BackwardTriple (1, 2.0, "3.0")
print (u)

I was expecting to see this printed:

("3.0", 2.0, 1)

but this is printed instead:

(1, 2.0, "3.0")

Could anyone explain why?

The order doesn't matter in generics declarations (the <T1, T2, T3> bit). It's conceptually an unordered list; just a declaration of what the generic type names are, nothing more.

Whereas the order of fields in a tuple is quite ordered. And is the order that's used for synthesised methods like init and [conceptually if not literally] description.

2 Likes

i remember from somewhere that changing the order of generic parameters changes the ABI name of a function, since the ABI doesn’t actually mangle the names of the parameters

1 Like
typealias BackwardTuple<A, B> = (B, A)

let x = BackwardTuple(123, "hello")

In this example, you're creating a BackwardTuple<String, Int> because the tuple expression (123, "hello") binds A = String and B = Int. What goes "backwards" here isn't the tuple value itself, but the generic parameters to BackwardTuple.

3 Likes

Could be - I don't know anything about that.

I'd be a little surprised, though - seems like the generic types would be given a deterministic order by the compiler in order to avoid that kind of sensitivity (or at least tied to the parameter order, to similar effect).

This works as expected.

typealias BackwardTriple <T1,T2,T3> = (T3, T2, T1)
let u = BackwardTriple (1, 2.0, "3.0")

Here, you're creating a BackwardTriple<String, Double, Int> aka. (Int, Double, String)