I’ve been programming in earnest for about 5 years. When I was just beginning, a lot of the way the computers and programming worked seemed like sheer magic. As I’ve gotten better at programming, a lot of that opacity has started to fade away. The illusions of abstraction are disappearing. It’s a little terrifying that the people who make the foundation of our technology aren’t that much smarter than me or you, but mostly this epiphany overjoys me. Nothing is inscrutable!
When I first started making iOS apps, I remember wiring up my IBAction
to a button in Interface Builder and thinking “Okay, but how is this method getting called?” If I’m remembering right, part of me thought that it might be some kind of polling loop. I also remember thinking that it couldn’t possibly be that stupid. Turns out, it is. NSRunLoop
is just a big while
loop that spins and makes your whole app go around.
Arrays are easy enough; they’re just an unbroken block of memory. With an index for an item, you can figure out what its memory location is: (offset + index*item_size)
. But how the heck do dictionaries (or hashes, or maps) work? How can they get instant access with a key that isn’t a number?
You’ve got to convert that key into a number, so you can put it into an array. (Turns out, this is one of the things you learn when you get a real computer science degree in a class called “Data Structures”. I had a degree-having friend explain it to me.) Take a big array, hash the key into a number (hence, the name “hash”), mod it by the size of the array so it’ll fit into one of the array’s slots, and insert it into a bucket at that index. When fetching, the key is hashed again, and it should fall into the same spot in the array, and you can get the item from the bucket. It’s not magic, even though it certainly feels like it. Here’s a good Mike Ash post with code explaining how NSMutableDictionary
is written.
The big kahuna: compilers. How do they work? You could go read the daunting Structure and Interpretation of Computer Programs (which I promise I will do one of these days), or read this relatively short (16,000-word) blog post that explains how to write a lexer, parser, and evaluator for small subset of Lisp. It took me about two hours to get through, but in the end I had a pretty good sense for how Lisp (probably the simplest programming language) was parsed and compiled. How do you make this Lisp compile down to machine code? I don’t know. Yet.
Richard Feynman, when asked if understanding our world via science removes its magic, responds with a parable about an artist:
He’ll hold up a flower and say “look how beautiful it is,” and I’ll agree. Then he says “I as an artist can see how beautiful this is but you as a scientist take this all apart and it becomes a dull thing,” and I think that he’s kind of nutty. […] All kinds of interesting questions which the science only adds to the excitement, the mystery and the awe of a flower. It only adds. I don’t understand how it subtracts.
Garbage collectors; NSCache
; image convolution; UIScrollView
; bloom filters: with all of it, there’s no voodoo. Even if it feels like a black box that you’ll never be able to peer into, it’s all just code. No matter how many stupid arcane meaningless equations are on the Wikipedia page, it’s simpler than that.
It’s all just bits and bytes that are arranged in nice ways that have nice ramifications. You can understand those bits and bytes, and knowing that the computing world has order is essential to understanding that you can affect it and improve it.