Holy War: Type aliases

Kyle Cardoza writes: Erica, Is it considered bad style to typealias OpaquePointer when you have to deal with OpaquePointer values that point to different types? The typealiases make the code read so much nicer…

Using typealiases to create “pseudotypes” (where typealiases essentially duplicate a single  type) neatly organizes your code. I endorse any solution that emphasizes semantics and supports readability. As OpaquePointer is not generic, it doesn’t encapsulate type information the way Array<Int> or Set<String> do:

// Both are typed to OpaquePointer, so nothing concrete
// distinguishes the two roles.
// let p1 = OpaquePointer(unsafeMutableRawPtr1)
// let p2 = OpaquePointer(unsafeMutableRawPtr2)

Building convenience typealiases emphasizes the distinction between otherwise structurally identical uses. This differentiates each use-point and provides built-in “type commentary”:

typealias OpaqueType1Pointer = OpaquePointer
typealias OpaqueType2Pointer = OpaquePointer

let p1: OpaqueType1Pointer = OpaquePointer(rawPtr1)
let p2: OpaqueType2Pointer = OpaquePointer(rawPtr2)

// or, thanks Nil, directly:

let p1 = OpaqueType1Pointer(rawPtr1) 
let p2 = OpaqueType2Pointer(rawPtr2)

You might consider an alternative. If you’re willing to trade off a little overhead against enhanced type safety, you might introduce a simple value type. Wrapping the opaque pointer enables you to use a type-specific initializer. Here’s an extremely rough example of what that might look like:

struct SometypeWrapper {
    let opaque: OpaquePointer
    init(value: Sometype) {
        opaque = OpaquePointer(Unmanaged
            .passRetained(value).toOpaque())
    }
}

What do you think? Good use of type aliases? Bad? Or should you always go with a wrapper? Let me know. Drop a note in the comments or send over a tweet.

Thanks, Mike Ash

3 Comments

  • You can also ‘initialize’ a typealias:


    typealias OpaqueType1Pointer = OpaquePointer
    typealias OpaqueType2Pointer = OpaquePointer

    let p1 = OpaqueType1Pointer(rawPtr1)
    let p2 = OpaqueType2Pointer(rawPtr2)

  • Would a generic typealias make sense here, to at least attribute the kind of pointer we’re talking about?


    typealias OpaqeTypedPointer = OpaquePointer
    let p1 : OpaqueTypedPointer<Array> = OpaquePointer(rawIntArrayPointer)

  • Looks like my generic parameter in the typealias declaration got filtered out there?

Join the Discussion

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>