Seibeclass="underline" You just mentioned papers from the academy and from industry. Do you have any sense of whether those two meet in the right place these days?
Fitzpatrick: They kind of feel about the same to me. But it’s more interesting, a lot of times, to read the industry ones because you know they did it to solve a problem and their solution works as opposed to, “We’d think it would be cool if—” There’s a lot of crazier stuff that comes out of academia and it doesn’t actually work, so it’s just a crazy idea. Maybe they turn it into commercial things later.
Seibeclass="underline" How do you design software?
Fitzpatrick: I start with interfaces between things. What are the common methods, or the common RPCs, or the common queries. If it’s storage, I try to think, what are the common queries? What indexes do we need? How are the data going to be laid out on disk? Then I write dummy mocks for different parts and flesh it out over time.
Seibeclass="underline" Do you write mocks in the test-first sense so you can test it as you go?
Fitzpatrick: More and more. I always designed software this way, even before testing. I would just design interfaces and storage first, and then work up to an actual implementation later.
Seibeclass="underline" What form would the design take? Pseudocode? Actual code? Whiteboard scribbles?
Fitzpatrick: Generally I would bring up an editor and just write notes with pseudocode for the schema. After it got good, I would make up a real schema and then I would copy-paste it in just to make sure that “create table” works. Once I got that all going, I’d actually go implement it. I always start with a spec.txt first.
Seibeclass="underline" After you write a bunch of code do you ever discover that you really need to reconsider your original plan?
Fitzpatrick: Sometimes. But I’ve started with the hard bits or the parts I was unsure of, and tried to implement those parts first. I try not to put off anything hard or surprising to the end; I enjoy doing the hard things first. The projects that I never finish—my friends give me shit that it’s a whole bunch—it’s because I did the hard part and I learned what I wanted to learn and I never got around to doing the boring stuff.
Seibeclass="underline" Do you have any advice for self-taught programmers?
Fitzpatrick: Always try to do something a little harder, that’s outside your reach. Read code. I heard this a lot, but it didn’t really sink in until later. There were a number of years when I wrote a lot of code and never read anyone else’s. Then I get on the Internet and there’s all this open source code I could contribute to but I was just scared shitless that if it wasn’t my code and the whole design wasn’t in my head, that I couldn’t dive in and understand it.
Then I was sending in patches to Gaim, the GTK instant-messenger thing, and I was digging around that code and I just saw the whole design. Just seeing parts of it, I understood. I realized, after looking at other people’s code, that it wasn’t that I memorized all my own code; I was starting to see patterns. I would see their code and I was like, “Oh, OK. I understand the structure that they’re going with.”
Then I really enjoyed reading code, because whenever I didn’t understand some pattern, I was like, “Wait, why the fuck did they do it like this?” and I would look around more, and I’d be like, “Wow, that is a really clever way to do this. I see how that pays off.” I would’ve done that earlier but I was afraid to do it because I was thinking that if it wasn’t my code, I wouldn’t understand it.
Seibeclass="underline" And how do you tackle reading other people’s code? For starters, do you read code just to see how it works overall, or do you always go in with some change you want to make?
Fitzpatrick: Generally I wanted to change something. Or if you really respect some programmer, go read some of their code. Maybe that’ll make you realize that they’re mortal and they’re not really someone you should be idolizing. Or you learn something about their code.
Seibeclass="underline" So say you’ve got a change you want to make; how do you tackle it?
Fitzpatrick: First step, take a virgin tarball or check out from svn, and try to get the damn thing to build. Get over that hurdle. That tends to be the hugest hurdle for most people—dependencies in the build system or they’re assuming this library is installed. I almost wish that these large projects just came with a virtual machine that was the build environment.
Seibeclass="underline" You mean like a VMware virtual machine?
Fitzpatrick: Yeah, so if you just want to get into hacking on it really quickly, here’s all the dependencies. People’s connections are getting quick enough. That’s totally viable.
Anyway, once you have one clean, working build, kill it, and just make one damn change. Change the title bar to say, “Brad says, ‘Hello world.’” Change something. Even if everything’s ugly, just start making changes.
Then send out patches along the way. I find that’s the best way to start a conversation. If you get on a mailing list and you’re like, “Hey, I want to add a feature X,” the maintainer is probably going to be like, “Oh fuck, I’m so busy. Go away. I hate feature X.” But if you come to them and you’re like, “I want to add feature X. I was thinking something like the attached patch,” which is totally wrong but you say, “But I think it’s totally wrong. I’m thinking the right way might be to do X,” which is some more complex way, generally they’ll be like, “Holy crap, they tried, and look, they totally did it the wrong way.”
Maybe that pains the maintainer. They’re like, “Oh man, I can’t believe they went through all that effort to do it. It’s so easy to do it the right way.” Or, “Oh, wow, they did all this work in the wrong direction. I hope they don’t go in that direction any more.” And then they reply.
That’s always the best way to start a conversation. Even at Google, that’s the way I start a lot of conversations to a team I don’t know. When I fix a bug in their product the first thing I do is send them a patch in the mail and just say, “What do you guys think of this?” Or on the internal code-review tool I’d be like, “Here is a review. What do you think?” They could just say, “Fuck no, that’s totally the wrong fix.”
Seibeclass="underline" Do you still read code for fun, as opposed to reading it because you need to work with it?
Fitzpatrick: Sometimes. I checked out Android source code for no real reason. The same with Chrome; when it went open source, I mirrored the repo and just looked around. I did the same thing with Firefox and Open Office. Some program you’ve been using and all of a sudden you have access and you might as well look.
Seibeclass="underline" Programs like that, the code base is pretty huge. When you look at something like that for fun, how deeply do you get into it?
Fitzpatrick: Generally, I’ll just pipe find into less and try to understand the directory structure. Then either something grabs my eye or I don’t understand what something is. So I pick a random file and get a feel for it. Then I bounce around and wander aimlessly until I’m bored and then pick a new random spot to jump in.
A lot of times, I’ll work on building it in parallel with reading it because they’re very parallelizable tasks, especially if it’s hard to build. By the time it’s finally built, then I can start tweaking it if I want to.
Seibeclass="underline" So when you read good code it either fits into patterns that you already understand, or you’d discover new patterns. But not all code is good. What are the first warning signs of bad code?
Fitzpatrick: Well, I’m particularly snooty now, having worked at Google with really strict style guidelines in all languages. On our top six or seven languages, there’s a really strict style guide that says, “This is how we lay out our code. This is how we name variables. This is how we do spacing and indentation, and these patterns and conventions you use, and this is how you declare a static field.”