books chapter one
I wanted to read, or reread, some books, but couldn’t decide which ones, so figured reading all of them at once would be the best solution. In particular, I’d read Coders at Work about the time it came out, and liked it, then skimmed it again recently. The second time through I still liked it, but I noticed new things. I should reread the whole thing. And what about these other books I’m always certain to install on each Kindle but never quite read? My favorite unread books.
There’s Coders at Work, 15 interviews with people who code. There’s the book that inspired it, Founders at Work, which also contains some good development advice along with the business ideas. That’s 32 chapters, so double time through this one. There’s the Mythical Man-Month, 15 or 18 or so chapters. The Pragmatic Programmer has 8 chapters, of a great many sections each, so that can be read at half speed. At some point in the past I read most of Programming Pearls and liked it, but don’t have a copy at hand, so instead the last selection is something a little different, Code: The Hidden Language of Computer Hardware and Software. 25 chapters, start with two per week and slow down for the hard stuff. That’s five books, which is probably pushing the limit of my ability to consume words requiring thought. At least the chapters for most books are independent, so I won’t have to remember anything.
coders
Our first victim is Jamie Zawinski, who wrote a text editor and a browser. But before all that, he was working in Lisp, which is a lovely language. jwz also has opinions about C, and perl, and something called C++. While at Lucid, building an IDE out of emacs, he was in charge of vi emulation. “The real problem with that wasn’t so much that it was emulating vi wrong as that vi users quit and restart vi all the time. And no amount of coding on my part is going to get them out of that mindset.” This is a true observation.
The early Netscape team was only one or two people per project: networking, layout, platform specific front end. They got a lot done in only six months, but basically only by working non stop. And rushing to get things done meant some of the quality wasn’t top notch. But there’s no time to rewrite because you’re immediately on to the next thing. All of which sounds about right. You can get a lot done working independently. Though I’ve worked some places where the motto was closer to there’s no time to do it right, but there’s always time to do it over. I guess if you don’t even have time to do it over, you’re really going to feel the pinch.
And then Collabra bought Netscape. No, wait, other way around, but Collabra ate Netscape from within and ruined everything by using threads. And also, compromising the cross platform portability by releasing Windows first, and then porting later. Mixed thoughts on this. Developing for one platform and then porting to another has resulted in some pretty compromised results. A lot of little assumptions sneak into the code and it takes a long time to fix, and some of the assumptions don’t get noticed and then you ship something broken. In many ways, portability is an attribute a lot like being able to compile. If your code doesn’t compile, or doesn’t work, but you keep plowing ahead bad things will happen. Similarly with disregarding portability to get things done. On the other hand, OpenSSH is developed for OpenBSD first, then ported, and I think the results turn out ok. Sometimes you just want to look at the code for one platform to see how things are supposed to work without getting tied down in all the reality. jwz also mentions porting XScreenSaver to OS X by reimplementing Xlib in terms of Cocoa, so he didn’t have to change the main code base. This approach often works really well. Pick one platform, then make the other platforms be that platform. Your code is always portable, but it’s always concrete, in terms of a known platform, not an abstraction layer that exists nowhere else.
“Usually by the second or third time you’ve cut and pasted that piece of code it’s like, alright, time to stop cutting and pasting and put it in a subroutine.” I like the rule of three most of the time. It’s ok to duplicate code because you don’t know yet what the common elements should be. Once you’ve done something three times, you know what it is you’re doing.
There’s also a lot more talk about rewriting. It’s fun to write new code, to do it the right way, to replace this thing somebody else wrote which you’d have to study to understand. But the result is nothing is ever quite done. The year of the Linux desktop will be next year, for sure.
founders
Max Levchin founded PayPal. An interesting tale of continuously pivoting and refocusing the product. He started out writing a crypto library. But nobody was much interested in writing software, or at least not software that needed a secure crypto library. So he switched to writing such software, a password keeper. But users didn’t seem to care much about securing their bank password, either. So he switched to storing money directly. Now suddenly users were interested. You could securely beam crypto money from one Palm Pilot to another. And then, almost as an afterthought, to show people how cool life would be carrying a crypto wallet on your Palm Pilot, they built a web interface that let people without PDAs send money. And boom, people liked this. A lot. The crypto money of the future was quickly killed in favor of boring old web banking. What I found interesting is how he had to keep climbing up the stack, in theory shrinking his market. The crypto library he started with could have been used not just by PayPal, but also by their competitors, and the password keepers, and everybody else. That would be a much bigger market. But nobody was interested in his shovels, so he had to go out and do the digging himself.
In the early days, advisors told him he’d be buried by fraud. Fraud? What fraud? I don’t see any fraud. Until you wake up one day, the day after somebody has figured out how to do automated chargebacks, and boom. You’ve got fraud. And now you’re in fire fighting mode, trying to solve this problem in real time even as it keeps getting worse. I liked two things about this story. Sometimes insiders really do have some domain specific knowledge about what makes things harder than they seem. And things can go from no problem at all to full on conflagration pretty quickly. On the other hand, he says that one reason the banks took so long to tackle personal payments is their zero risk attitude. They knew there would be fraud, and they weren’t willing to bleed money until they solved it. Sometimes a problem isn’t solved except by someone who encounters it too late and has no choice, while everyone else does their best to avoid it entirely.
On the importance of reporting and visualization. Early fraud fighting was done by hand, by reviewing transactions. It wasn’t effective. So they built some special tooling, which did two things. It let them see what was happening, where the money was going. And it predicted and prioritized what were likely to be the largest losses, which wasn’t possible just from looking at thousands of pages of printouts.
Sabeer Bhatia founded Hotmail. It was supposed to be a different company, but he couldn’t send personal email to his cofounder through the corporate firewall. A web gateway to email solved that problem. And then it turned out to be convenient for other people, too.
He has some theories about software development. He comes from a hardware background, where you have to get things right the first time because it’s very expensive to fix afterwards. No patching. And thus they make better software developers because they’re more methodical and understand state machines and so forth. I’m not sure I agree with this; the perception in my circles is that hardware engineers write the worst software (usually monstrous piles of poo pretending to be device drivers). But of course, there could be a difference between a hardware engineer temporarily forced to write a driver before getting back to the fun stuff, and a hardware engineer turning to software development full time. His point about the approach one takes is a good one. When you model software as a deterministic function, that takes some inputs and produces some outputs, that leads to a better result. The ship then patch mentality trends towards the lower end of the quality spectrum.
Crazy story: one person didn’t type hotmail.com into the location bar, but went to Yahoo and searched for Hotmail and clicked on that. Of course, people still do that today, though possibly with less Yahoo. I find it funny that he found this behavior unbelievable in 1997, a time when URLs were probably very new to many people. Getting to websites through a portal would have been pretty natural. And a great deal of Hotmail’s success was because they made it easy for unsophisticated users to use email. So don’t be surprised that users find a different way of doing things than you do.
“If you are expecting people to dramatically change the way they do things, it’s not going to happen. Try to make it such that it’s a small change, yet an important one.” A true observation. People are going to do things the way they like doing them, and they’re not going to stop using vi. Oh, wait, different interview.
man-month
Programming is a tar pit. The more you struggle, the slower you go and the more you’re sucked down. Nevertheless, each individual limb is free to move. What could be the problem? This is a great analogy. You can be drowning in tar for quite some time before you realize what’s happening, and then it’s often too late.
We begin by considering the two programmers in a garage that get things done. A classic myth that’s generally expressed today as “I could build that in a weekend.” Don’t even need a second programmer or a garage. But the output of our lonesome programmers is a mere program. It’s not a product, complete with documentation that doesn’t crash on unexpected input. That’s three times the effort. Nor is it a system, which is to say it’s not reusable, with standardized interfaces. There’s another three times effort. So all told, turning a one off program into something one might reasonably sell requires a nine fold increase in effort. Easier to start things than to finish them.
The joys and woes of programming. Programming is fun because we get to learn and build things. We can see our ideas take form. But then reality sets in. There’s always one more bug to fix, which isn’t very fun, and sometimes we have to depend on other people’s code, which is always the worst.
And then there’s the sense of dread, as a project nears completion, that it’s already obsolete because people are looking ahead to the next version. Or a competitor’s product, which promises to do more. Why even finish? One good reason is that next version is likely to be late, over promise, and under deliver. I liked this as a counterpoint to the sense of urgency expressed by others. In a sense, he’s saying the same thing. Something that ships has much more value than vapor. But everyone else is dealing with the same constraints and pressures.
pragmatic
1. You are responsible for your work, even if the cat eats your source code. Provide options, not excuses. Eh, meh.
2. Software is susceptible to entropy. Pay attention to how things are going, and fix up the broken things before they get worse. (Otherwise you end up being Netscape.) A reference is made to the broken windows theory. Somewhere on the OpenBSD web site it states “Do not let serious problems sit unsolved.” So this sounds like pretty good advice, though of course it’s subject to some interpretation, which is probably the hard part.
3. The parable of stone soup is related, wherein everybody contributes a little something, even if only reluctantly, and suddenly there’s a pot of delicious soup for all to enjoy. A bonus parable of the boiling frog is related as well. The foreword to this book promised that every tip was concrete advice drawn from experience. I suppose one could make stone soup from concrete blocks as well.
code
I’m pretty excited about this book, which is actually a new addition to the collection, and one I haven’t tried reading before.
The word code is often associated with computers and programming (not surprisingly that’s the common usage in all the previous books as well), but really it can be any system of transferring information. I want to send you a message by waving a flashlight, perhaps using Morse code. That’s a code. Codes can be arbitrary. Why are dogs called “dogs” and not “cats“? The important property of a code is that it be intelligible. So codes aren’t just in computers, they’re everywhere. Some codes may be arbitrary, but some, like Morse, are designed to be efficient. Common letters are assigned shorter sequences.
Speaking of Morse, apparently during WWII the BBC would play the Fifth Symphony opening, dih dih dih dah, because that’s V. For Victory. Of course, Beethoven didn’t intend to convey that meaning. The book glosses over this (at least for now), but I think it’s an important point. The reinterpretation and misinterpretation of codes can be very powerful. We can’t change what someone says, but we can change what they mean. And in reverse, of course. So that’s something to think about.
Key observation about Morse: dots and dashes. Two symbols. Two. Apparently this is important. Little foreshadowing.
Chapter two continues our investigation of Morse. The typical table maps letters to dots and dashes, which makes it easy to send. But decoding an incoming message requires scanning the second column of a table with no apparent ordering. Imagine how much easier it would be to use a reverse lookup table. While building our reverse table, we might notice that it can also be represented as a tree, with each node branching dot or dash. At the top we have E and T, dot and dash. Each level we add to the tree doubles the number of letters, plus numbers and symbols, we can represent. And if we extend things all the way to 8 levels, 8 possible dots or dashes, that may even be enough to represent a great many symbols.
coda
Take your time. Do things right. But don’t take too long. Get things done. Life sure is hard. Unless you’re Goldilocks and everything is just right.
A common theme does seem to be that it’s easy, in the moment, for the sake of expediency, to cut a corner. And maybe this is even the best thing to do for now. But such quick hacks have a tendency to pile up until they become the only way to get things done. So keep a weather eye out.
Code that doesn’t ship isn’t worth much. Heard that a couple times. But at what cost?