Stop mutating, evolve

NSData, My Old Friend

Or… “How I learned to stop worrying, and love Foundation.”

Forgive me, NSData. I was running around with that flashy [UInt8], acting like you didn’t have everything I need. I’ve learned my lesson.

—– Rob Napier (@cocoaphony) September 28, 2015

I did a lot of writing and rewriting of the Swift version of RNCryptor. I struggled especially with what type to use for data. I gravitated quickly to [UInt8] with all its apparent Swiftiness. But in the end, after many iterations, I refactored back to NSData, and I’m really glad I did.

This is the story of why.

Type-erasure in Stdlib

When last we talked about type erasure, I described an easy way to build type erasures using closures. And I mentioned:

(While this works exactly like AnySequence, this isn’t how AnySequence is implemented. In my next post I’ll discuss why and how to implement type erasers like stdlib does.)

At the time I thought I’d pretty well nailed it down, but every time I dug into it I found another little thing I’d missed, and it never seemed to end. And with stdlib open sourcing soon, you’ll all just be able to read this yourselves, so why embarrass myself getting it all wrong? Over time I kind of hoped you all had forgotten that comment and planned to move on to other things. But then I was busted by Michael Welch, and so I had to finish the spelunking and here you go.

A Little Respect for AnySequence

Once upon a time, when Swift was young, there were a couple of types called SequenceOf and GeneratorOf, and they could type erase stuff. “Type erase?” you may ask. “I thought we loved types.” We do. Don’t worry. Our types aren’t going anywhere. But sometimes we want them to be a little less…precise.

In Swift 2, our little type erasers got a rename and some friends. Now they’re all named “Any”-something. So SequenceOf became AnySequence and GeneratorOf became AnyGenerator and there are a gaggle of indexes and collections from AnyForwardIndex to AnyRandomAccessCollection.

So what are these type erasers? Let’s start with how to use one and we’ll work backwards to why.

Product or Process?

Forgive a slight divergence. I’ll bring it back to software development before the end.

A friend of mine is an arborist. He takes care of a large forest, trimming and culling trees. He’s quite good at it and enjoys it, but he’s worried about job security. He thinks cabinet making would be a good career move. He likes to work with wood, and high-end cabinets are very expensive so there’s clearly a lot of money there. I’m a hobbyist woodworker, so we were talking about it.

Throw Money at It

My dad has always been an engineer, but by the end of his career he had three-letter titles starting with “C”. And all my life he’s taught me lessons, but the most important ones to me professionally were never about technical matters; they were always the talks about how large companies work. Watching some of the reactions from devs to the recent Taylor Swift/Apple back-and-forth, I realized that one of my dad’s lessons might be helpful to others.


Last time we talked about how a function that can throw errors is a different type in Swift than a function that cannot throw errors. And then I briefly mentioned this other thing, “rethrows.” Let’s talk about that, and along the way explore closure types a little more and their weird and woolly ways.

Throw What Don’t Throw

So say you are trying out all this interesting new throw stuff in Swift 2. And say you’re running an early Beta in which many stdlib functions don’t handle throw closures yet. Or maybe you’re in the future and dealing with some other piece of code that you wish could handle a throw closure, but doesn’t. What do you do?

I, for One, Welcome Our New Haskell Overlords

Manuel Chakravarty made a comment a few weeks ago:

By not using standard FP terminology in emerging languages like Swift, we deny learners access to a lot of existing literature.

I certainly agree. But there’s a lot more to it, and I hope the functional programming community will get involved in new ways. We’ll get there. First, a little history for the rest of us. FP folks, I’ll get back to you in a couple of sections.

Go Is a Shop-built Jig

Alex Payne wrote an excellent essay called Thoughts on Five Years of Emerging Languages. It called to mind something I wrote a while ago for a limited audience that I never got around to turning into a public form. Thanks to Manuel Chakravarty for the link and the inspiration.

For those who read my blog for Cocoa (and recently Swift) discussion, you may be surprised that most of my professional work right now is in Go, C, and C++ (in that order). So I thought I might take a moment to discuss Go.

First, it’s important to say that I really like Go. I didn’t think I would. I’m a language snob at heart. Before Swift, I’d been spending a lot of time on the functional side of the street with a brief dallience with actors. I was just about to do deeper into the parens, when I wound up taking a side trip into Google-land and Go. I’d dipped my toe into the water once before and been turned off by what seemed to be the sloppiness of the language. How variables are declared bugged me (turns out it bugs the lead language designer, too). The multiple return types of range bugged me. Strings switching between code points and bytes bugged me. The fact that Go can’t implement its own append() harkened back to funky Perl magic. Go just seemed sloppy and under-considered.