By Paul Graham, O’Reilly Media, Inc., May 2004, 0596006624

Paul Graham compares hacking to painting in that hacking is an art of munging code continuously, and painting was not able to do this until the invention of oil paints. The Renaissance created great painters, because they finally had a great medium to paint with. The book consists of articles from his website. In some sense, it may not be worth buying, but it does come together nicely, and it is handy to hold.

Graham is an eloquent writer. Yet, he is often immature or naive; I’m not sure which. “Most adults, likewise, deliberately give kids a misleading view of the world.” To me, we limit a child’s world so children can assimilate its complexity, not because we want to mislead children. Our goal is to teach, just like we teach Newtonian mechanics as if it were the “whole truth”, we let children believe in myths to allow their moral sense and view of the world to develop slowly with their slowly developing brain.

On the programming side, Graham does not feel that testing is all that important. “[At Viaweb, there was no protection against breakage except the fear of looking like an idiot to one’s peers, and that was more than enough.” Repeatable regression testing is what makes software fungible. If you don’t have a way to testing your past assumptions, you don’t know if you broke any of them. It seems to me that Graham hasn’t maintained many systems over a long enough period of time.

Here’s another example: “In hacking, like painting, work comes in cycles.” This is silly. I perform consistently unless I’m scared. When I’m scared, it’s due to a psychological issue, not a complex problem. I’ve learned over time to recognize when I’m afraid and, more importantly, to accept it. My next step is to address the issue head on.

Graham goes on to say that he saves up little tasks for those periods when he is uninspired, e.g. debugging. “I like debugging: it’s the one time that hacking is as straightforward as people think it is.” Most programmers are afraid of debugging. Indeed, I was once laughed at by a room full of about 400 programmers who thought I was crazy when I said debugging was the easy part.

When Graham is inspired, he is in flow, and fear is not a factor. Flow is extremely important, and I’ve learned that the best way to get into flow is to take a step in any direction. Then I take another, and another, and soon, I’m back in flow again.

This is not about cycles, rather it is about learning to overcome your fears. Cycles are not mythical boogeymen that come out of nowhere. And, I bet, when Graham is inspired, he may also be driven by fear, that is, the fear he has to work 16 hours in a row or he’ll lose his flow or worse, lose the idea completely. This would surely be a sign of a deeper psychological issue lurking in the shadows.

That being said, Graham is a master of rhetoric, and the book is a fun read.

[p24] The other problem with startups is that there is not much overlap between the kind of software that makes money and the kind that’s interesting to write. Programming languages are interesting to write, and Microsoft’s first product was one, in fact, but no one will pay for programming languages now. If you want to make money, you tend to be forced to work on problems that are too nasty for anyone to solve for free.

All makers face this problem. Prices are determined by supply and demand, and there is just not as much demand for things that are fun to work on as there is for things that solve the mundane problems of individual customers.

[p29] Great software, likewise, requires a fanatical devotion to beauty. If you look inside good software, you find that parts no one is ever supposed to see are beautiful too. When it comes to code I behave in a way that would make me eligible for prescription drugs if I approached everyday life the same way. It drives me crazy to see code that’s badly indented, or that uses ugly variable names.

If a hacker were a mere implementor, turning a spec into code, then he could just work his way through it from one end to the other like someone digging a ditch. But if the hacker is a creator, we have to take inspiration into account.

In hacking, like painting, work comes in cycles. Sometimes you get excited about some new project and you want to work sixteen hours a day on it. Other times nothing seems interesting. q To do good work you have to take these cycles into account, because they’re affected by how you react to them. When you’re driving a car with a manual transmission on a hill, you have to back off the clutch sometimes to avoid stalling. Backing off can likewise prevent ambition from stalling. In both painting and hacking there are some tasks that are terrifyingly ambitious, and others that are comfortingly routine. It’s a good idea to save some easy tasks for moments when you would otherwise stall.

In hacking, this can literally mean saving up bugs. I like debugging: it’s the one time that hacking is as straightforward as people think it is. You have a totally constrained problem, and all you have to do is solve it. Your program is supposed to do x. Instead it does y. Where does it go wrong? You know you’re going to win in the end. It’s as relaxing as painting a wall.

[p30] As far as I know, when painters worked together on a painting, they never worked on the same parts. It was common for the master to paint the principal figures and for assistants to paint the others and the background. But you never had one guy painting over the work of another.

I think this is the right model for collaboration in software too. Don’t push it too far. When a piece of code is being hacked by three or four different people, no one of whom really owns it, it will end up being like a common-room. It will tend to feel bleak and abandoned, and accumulate cruft. The right way to collaborate, I think, is to divide projects into sharply defined modules, each with a definite owner, and with interfaces between them that are as carefully designed and, if possible, as articulated as programming languages.

[p31] Most makers make things for a human audience. And to engage an audience you have to understand what they need. Nearly all the greatest paintings are paintings of people, for example, because people are what people are interested in.

Empathy is probably the single most important difference between a good hacker and a great one. Some hackers are quite smart, but when it comes to empathy are practically solipsists. It’s hard for such people to design great software [5], because they can’t see things from the user’s point of view.

[p32] You need to have empathy not just for your users, but for your readers. It’s in your interest, because you’ll be one of them. Many a hacker has written a program only to find on returning to it six months later that he has no idea how it works. I know several people who’ve sworn off Perl after such experiences.

[p40] Most adults, likewise, deliberately give kids a misleading view of the world. One of the most obvious examples is Santa Claus. We think it’s cute for little kids to believe in Santa Claus. I myself think it’s cute for little kids to believe in Santa Claus. But one wonders, do we tell them this stuff for their sake, or for ours?

[p69] At Viaweb, as at many software companies, most code had one definite owner. But when you owned something you really owned it: no one except the owner of a piece of software had to approve (or even know about) a release. There was no protection against breakage except the fear of looking like an idiot to one’s peers, and that was more than enough. I may have given the impression that we just blithely plowed forward writing code. We did go fast, but we thought very carefully before we released software onto those servers.

[p95] For most people the best plan probably is to go to work for some existing company. But it is a good idea to understand what’s happening when you do this. A job means doing something people want, averaged together with everyone else in that company.

Working Harder

That averaging gets to be a problem. I think the single biggest problem afflicting large companies is the difficulty of assigning a value to each person’s work. For the most part they punt. In a big company you get paid a fairly predictable salary for working fairly hard. You’re expected not to be obviously incompetent or lazy, but you’re not expected to devote your whole life to your work.

[p100] Steve Jobs once said that the success or failure of a startup depends on the first ten employees. I agree. If anything, it’s more like the first five. Being small is not, in itself, what makes startups kick butt, but rather that small groups can be select. You don’t want small in the sense of a village, but small in the sense of an all-star team.

[p102] If you can develop technology that’s simply too hard for competitors to duplicate, you don’t need to rely on other defenses. Start by picking a hard problem, and then at every decision point, take the harder choice.

[p105] Venture capitalists have a list of danger signs to watch out for. Near the top is the company run by techno-weenies who are obsessed with solving interesting technical problems, instead of making users happy. In a startup, you’re not just trying to solve problems. You’re trying to solve problems that users care about.

[p167] In practice, writing programs in an imaginary hundred-year language will work to varying degrees depending on how close you are to the core. Sort routines you can write now. But it would be hard to predict now what kinds of libraries might be needed in a hundred years. Presumably many libraries will be for domains that don’t even exist yet. If SETI@home works, for example, we’ll need libraries for communicating with aliens. Unless of course they are sufficiently advanced that they already communicate in XML.

At the other extreme, I think you might be able to design the core language today. In fact, some might argue that it was already mostly designed in 1958.

[p191] In fact, choosing a more powerful language probably decreases the size of the team you need, because (a) if you use a more powerful language you probably won’t need as many hackers, and (b) hackers who work in more advanced languages are likely to be smarter.

[p192] If you start a startup, don’t design your product to please VCs or potential acquirers. Design your product to please the users. If you win the users, everything else will follow. And if you don’t, no one will care how comfortingly orthodox your technology choices were.

[p195] As an illustration of what I mean about the relative power of programming languages, consider the following problem. We want to write a function that generates accumulators– a function that takes a number n, and returns a function that takes another number i and returns n incremented by i. (That’s incremented by, not plus. An accumulator has to accumulate.)

In Common Lisp this would be

(defun foo (n)
  (lambda (i) (incf n i)))

In the book, he includes a Ruby example here “it’s almost identical”, but I took the text from his website, which was written in May 2002, when Ruby wasn’t popular – falling a bit into the trap, he is trying to tell us not to fall into.

[p195] and in Perl 5,

sub foo {
    my($n) = @_; sub {$n += shift}

which has more elements than the Lisp version because you have to extract parameters manually in Perl.

[p213] Users are a double-edged sword. They can help you improve your language, but they can also deter you from improving it. So choose your users carefully, and be slow to grow their number. Having users is like optimization: the wise course is to delay it. Also, as a general rule, you can at any given time get away with changing more than you think. Introducing change is like pulling off a bandage: the pain is a memory almost as soon as you feel it.

The above is from an earlier essay (2001) than his other essays about users. It seems to me he is contradicting himself about users, but his opinion may have changed. The next quote is from 2003, and he seems to think that users are essential to good design, not an optimization.

[p217] This focus on the user is a kind of axiom from which most of the practice of good design can be derived, and around which most design issues center.

[p219] In the software world, this idea is known as Worse is Better. Actually, there are several ideas mixed together in the concept of Worse is Better, which is why people are still arguing about whether worse is actually better or not. But one of the main ideas in that mix is that if you’re building something new, you should get a prototype in front of users as soon as possible.

The alternative approach might be called the Hail Mary strategy. Instead of getting a prototype out quickly and gradually refining it, you try to create the complete, finished, product in one long touchdown pass. As far as I know, this is a recipe for disaster. Countless startups destroyed themselves this way during the Internet bubble. I’ve never heard of a case where it worked.