Coders at Work is a collection of interviews with 15 programmers and computer scientists.
My impressions of this book are mixed. On the one hand the author found interesting interviewees and in addition to many funny anecdotes there are some nuggets in what they have to say, but on the other hand there is a lot of talk about old computers I didn't find that interesting and the author switched more than once the topic when I expected some follow-up questions. I also wished there were more younger interviewees to complement the greybeards' point of view on the craft of programming.
And he'd [Skef Wholey] come shuffling in with his ceramic mug of beer, bare feet, and he'd just stand behind me. I'd say hi. And he'd grunt or say nothing. He'd just stand there watching me type. At some point I'd do something and he'd go, "Ptthh, wrong!" and he'd walk away. [...] It was like the Zen approach – the master hit me with a stick, now I must meditate.
Certainly one of the most important things is writing code you can come back to later.
I wanted to be doing something that I could point to and say, "Look, I made this neat thing."
The sooner you realize that your map is wrong, the sooner you'll be able to figure out where it went wrong.
When you're debugging something and then you figure out that not only is the map wrong but the tools are broken – that's a good time.
So I write a new compiler and Stallman's response is, "I see no need for this change." And I'm like, "What are you talking about? It generates way faster code." Then his next response is, "Okay, uh, send me a diff and explain each line you changed." - "Well, I didn't do that – I rewrote it because the old one was crap." That was not OK. The only reason it ever got folded in was because I released it and thousands of people started using it and they loved it and they nagged him for two years and finally he put it in because he was tired of being nagged about it.
Do you like Perl or is it just handy? - Oh, I despise it. It's a horrible language. But it is installed absolutely everywhere. Any computer you sit down on, you're never going to have to talk someone through installing Perl to run your script. Perl is there already. That's really the one and only thing that recommends it.
It was just nice to be in that kind of environment where when someone says, "That's nonsense" or "We should do it this way", you can just take their word for it, believe that they know what they were talking about.
A month later two million people were running software I'd written. It was unbelievable. That definitely made it all worthwhile – that we'd had an impact on people's lives; that their day was more fun or more pleasant or easier because of the work we'd done.
At the end of the day, ship the fucking thing! It's great to rewrite your code and make it cleaner and by the third time it'll actually be pretty. But that's not the point – you're not here to write code; you're here to ship products.
When you inherit code from someone else, sometimes it's faster to write your own than to reuse theirs. Because it's going to take a certain amount of time to understand their code and learn how to use it and understand it well enough to be able to debug it. Where if you started from scratch it would take less time.
It's just more fun to write your own code than to figure out someone else's.
When you're looking at, "We've got to go from zero to done in six weeks", well, I can't do that unless I cut something out. And what I'm going to cut out is the stuff that's not absolutely critical. And unit tests are not critical. If there's no unit test the customer isn't going to complain about that.
I always wish people would comment more, though the thing that makes me cringe is when the comment is the name of the function rephrased. [...] You've got to say in the comment something that's not there already.
Not knowing something doesn't mean you're dumb – it just means you don't know it yet.
I got kicked off of AOL for writing bots, flooding their chat rooms, and just being annoying. [...] I also wrote a bot to flood their online form to send you a CD. I used every variation of my name, because I didn't want their duplicate suppression to only send me one CD, because they had those 100 free hours, or 5000 free hours. I submitted this form a couple thousand times and for a week or so the postman would be coming with bundles of CDs wrapped up.
Then one day I get a phone call and I actually picked up the phone, which I normally didn't, and it was someone from AOL. They were just screaming at me. "Stop sending us all these form submissions!" I'm not normally this quick and clever, but I just yelled back, "Why are you sending me all this crap? Every day the postman comes! He's dropping off all these CDs!" They're like, "We're so sorry, sir. It won't happen again."
I went through lots of styles, object-oriented stuff, and then functional stuff, and then this weird, hybrid mix of object-oriented and functional programming. This is why I really love Perl. As ugly as the syntax is and as much historical baggage and warts as it has, it never fucks with me and tells me what style to write in. Any style you want is fine.
He would sit outside on Wi-Fi, just hacking until we woke up, opened the door, and let him in.
I had to make rules for my mom, like, "If you call me, it has to be personal or business; whatever one you start with, that's how you end it. You can't switch from work to personal or personal to work." I just started hanging up on her if she switched.
It's always easier to do something right the first time than to do a migration with a live service.
You never learn something until you have to write something in it, until you have to live and breathe it. It's one thing to go learn a language for fun, but until you write some big, complex system in it, you don't really learn it.
I try not to put off anything hard or surprising to the end; I enjoy doing the hard things first.
But a lot of times lately, if there's something weird going on, I'm like, "OK, that function is too big; let's break that up into smaller parts and unit-test each one of them separately to figure out where my assumptions are wrong, rather than just sticking in random printlns."
Optimization is fun because it's not necessary.
I always hate computers. I don't think we've really made any progress in quite a long time. Computers seem slower, and crashier, and buggier than ever.
I remember all these porn sites started telling me they're using my file system. Well, that says something. I'm helping serve up porn.
Users always like to get the one with the higher version number even if it sucks more.
New must be better. Which is not always the case, but people hope it is. They want it to be.
All these browsers are always hanging and crashing and using tons of memory.
I don't really care if other people are better because I feel like there are tons of people who are better already. I figure we are always in the middle anyway, so I'm happy to stay in the middle.
I developed a lot of sensitivity really early on to the concerns of normal people as they play with these terrible machines and started looking at how we can make this stuff better for them.
The significance of the changes you can make to a language is related to the success of the language. The more successful the language is, the greater the cost of changing it. You have greater re-education costs and you have the potential costs of disruption which, as you become bigger, become unacceptable. When you're really successful, you need to be extremely cautious in any changes that you make. Whereas if you haven't made it yet, you have a lot more freedom in changing it around.
The whole web is built on one mistake after another. We have this big pile of accidents.
I think that is the most useful thing that a community of programmers can do for each other – spend time on a regular basis reading each other's code.
I think it's really difficult to write good code in a sloppy manner.
Readability of code is now my first priority. It's more important than being fast, almost as important as being correct, but I think being readable is actually the most likely way of making it correct.
Part of what makes programming difficult is most of the time we're doing stuff we've never done before. If it was stuff that had been done before we'd be reusing something else. For most of what we do, we're doing something that we haven't done before. And doing things that you haven't done before is hard. It's a lot of fun but it's difficult.
In my view, anybody who calls himself a professional programmer should have read Knuth's books or at least should have copies of his books.
I know that a lot of the things that I'm hoping to accomplish are not achievable. I'm aware of that. But every once in a while something works.
What I'm really allergic to, and what I had a bad reaction to in the '90s, was all the CORBA, COM, DCOM, object-oriented nonsense. Every startup of the day had some crazy thing that would take 200000 method calls to start up and print "hello, world".
Sound abstractions give you leverage over problems you couldn't address before.
There was some pressure from management to make the syntax look like Java. There was also some pressure to make it not too big, because after all, people should use Java if they're doing any real programming; this is just Java's dumb little brother.
Though Ruby does seem kind of overhyped. Nothing bad about it, just sometimes the fan boys make it sound like the second coming and it's going to solve all your problems, and that's not the case. We should have new languages but they should not be overhyped.
There's no silver bullet, but there are better languages and we should migrate to them as we can.
The worst bugs are the multithreaded ones.
You can learn a lot reading other people's code.
Bright people like each other and can judge each other – generally there's not a dysfunctional, "Hire my friend, who's really not bright". They want to work with bright people.
Impatience and hatred of primitive tools drives me to try to be a better programmer.
Having that ability to spread your approach and whatever you've learned about programming, and have that go through some kind of community and produce a corpus of code that's bigger than you could do, that's as satisfying to me as being the one that stays up all night writing too much code.
Basically I've become harder on myself over the years – that's what it takes to write good programs. You really can't accept bad habits from yourself.
The more things you learn and the younger you learn them, the better off you are.
A large part of every software engineer's job is writing prose. If you can't write precise, coherent, readable specs, nobody is going to be able to use your stuff.
The older I get, the more I realize it isn't just about making it work; it's about producing an artifact that is readable, maintainable, and efficient.
It's easier to optimize correct code than to correct optimized code.
When you choose a language, you're choosing more than a set of technical trade-offs – you're choosing a community. It's like choosing a bar. Yes, you want to go to a bar that serves good drinks, but that's not the most important thing. It's who hangs out there and what they talk about.
Starting is the hardest part, whether it's a program or a book or anything else.
Many things that you see in life, whether in architecture – the way buildings are constructed, in language – the way that communication occurs, many of these ideas can be retargeted. [...] So keeping your eyes open and being willing to reuse ideas is a good thing.
I believe that even for problems that aren't inherently mathematical, the kind of thinking that you learn in math is essential to programming.
The most important thing is to know what you're trying to build: what problem you're trying to solve. The importance of requirements analysis can't be overstated.
Many customers won't tell you a problem; they'll tell you a solution.
It doesn't matter how good you are; you can't get an API right until you've tried to code to it.
In most cases, programmer time is much more valuable than computer time. But that isn't necessarily so if you're running the same program on many, many thousands of machines.
Engineers have things that they're good at and things they're not so good at. There are people who would like to pretend that this isn't so, that engineers are interchangeable, and that everyone can and should be a total generalist. But this ignores the fact that there are people who are stunningly good at certain things and not necessarily so good at other things. If you force them all to do everything, you'll probably make mediocre products.
I think a big sin in our area, in engineering, is doing stuff just because it's neat, because it's good engineering, whatever. If you're not solving real problems for real users then you shouldn't add the feature.
A job with no job description is a really good job. Because then you can form it how you like.
Being a young programmer today must be awful – you can choose 20 different programming languages, dozens of frameworks and operating systems and you're paralyzed by choice.
The thing that really hasn't worked is software reuse.
It's worthwhile seeing if the direct route is quicker than the packaged route. In general I think if you buy software, or if you use other people's software, you have to reckon with an extremely long time to tailor it – it doesn't do exactly what you want, it does something subtly different. And that difference can take a very long time to solve.
It's incredibly difficult to get people to use new and better stuff.
Don't tell people how fast something is going to be before you've implemented it.
I like to figure out how things work. And a good test of that is to implement it yourself. To me programming isn't about typing code into a machine. Programming is about understanding.
Often when you explain things then you understand them better.
If you don't know what you're doing then I think it [pair programming] can be very helpful with someone who also doesn't know what they're doing. If you have one programmer who's better than the other one, then there's probably benefit for the weaker programmer or the less-experienced programmer to observe the other one. They're going to learn something from that. But if the gap's too great then they won't learn, they'll just sit there feeling stupid.
I don't think a program is finished until you've written some reasonable documentation. And I quite like a specification. I think it's unprofessional these people who say, "What does it do? Read the code." The code shows me what it does. It doesn't show me what it's supposed to do. I think the code is the answer to a problem. If you don't have the spec or you don't have any documentation, you have to guess what the problem is from the answer.
I like minimalistic code, very beautifully poised, structured code. If you start removing things, if you get to the point where if you were to remove anything more it would not work any more – at this point it is beautiful. Where every change that you could conceivably make, makes it a worse algorithm, at that point it becomes beautiful.
It had no permanent storage whatsoever so you had to type in your program every time you ran it.
To be an entrepreneur you need to get energy from stressful situations involving money, whereas my energy is sapped by stressful situations involving money.
Unless some people are working on radical and elegant things you're going to end up in a local optimum, incrementally optimizing the mainstream but stuck on a low hill.
I think it's important to do what you find motivating and interesting and follow it.
People often ask, "What's the equivalent of UML diagrams for a functional language?" And I think the best answer I've ever been able to come up with is, it's the type system. When an object-oriented programmer might draw some pictures, I'm sitting there writing type signatures.
Just getting the data types right, already you've said quite a lot about what your program does.
I think there's this horrible danger that people who are any good at anything get promoted or become more important until they don't get to do the thing they're any good at anymore.
One of the nice things about working in research is that instead of some manager standing over me saying, "This has to be done this week – just get it done", I can sit and look at something and say, "There must be a right way to do this."
I think it's good to remember that we're concerned with building things. I think that's why programming is so interesting.
I think a good attribute of a good programmer is they try to find a beautiful solution.
Your code should obviously have no bugs rather than having no obvious bugs.
Beautiful code is code that is obviously right.
That's the worst thing about long-lived programs... that they gradually become ugly.
The most depressing thing about life as a programmer, I think, is if you're faced with a chunk of code that either someone else wrote or, worse still, you wrote yourself but you no longer dare to modify.
After two years I said, "It took me four years to get sick of school and only two years to get sick of work, maybe I like school twice as much."
When I was in school, working as a team was called cheating.
I think understanding interfaces and how they go together is more important than all the details of the insides of these packages.
I think test-driven design is great. I do that a lot more than I used to do. But you can test all you want and if you don't know how to approach the problem, you're not going to get a solution.
One of the most important things for having a successful project is having people that have enough experience that they build the right thing. And barring that, if it's something that you haven't built before, that you don't know how to do, then the next best thing you can do is to be flexible enough that if you build the wrong thing you can adjust.
I've got to admit, I often end up rewriting. Sometimes I do that without ever finding the bug. [...] Sometimes I feel guilty about that. Is that a failure on my part? I didn't understand what the bug was. I didn't find the bug. I just dropped a bomb on the house and blew up all the bugs and built a new house.
We have hundreds of millions of users and we can make a difference for them, and we can launch new services for them quickly. I think that's great. I can't imagine anything else I could be doing to have that level of impact.
Looking back I think I was the fortunate beneficiary of a number of interesting coincidences or blessings.
You should have an idea what the implementation is going to look like as you design the interface.
His [Trenchard More] contention was that if you took care of the edge cases then the stuff in the middle usually took care of itself.
You want to design the specification of what's in the middle in such a way that it naturally is also correct on the boundaries, rather than treating boundaries as special cases.
The one thing I am reasonably convinced of is that it's a mistake to think that one language solves all problems better than any other language, or even equally well. I really think that there are application areas for which particular languages are better suited.
I think it's not an accident that we often use the imagery of magic to describe programming. We speak of computing wizards and we think of things happening by magic or automagically. And I think that's because being able to get a machine to do what you want is the closest thing we've got in technology to adolescent wish-fulfillment.
Certainly, dealing with parallel processes has produced the most difficult-to-deal-with bugs.
You can't prove by testing that a program is bug-free, you can only prove that you failed to find any bugs with your tests.
I can think of lots of areas where trying to standardize, trying to all go in one direction, has suppressed creativity.
I hate to see computer-science departments that feel their role is to prepare people to work in an industry and the industry is going that way and therefore we have to teach our students that way. It's exactly the wrong thing to do. What you should be doing with your students is teaching them to think generally – think outside the box and plot the other courses we should be pursuing.
To think outside the box, you've got to be a little outside the box.
People should learn to think clearly and to question.
Whenever I have a computing environment to play with, I like to try new things in it. That's what's been so much fun about doing the Smalltalk systems I did. You start from pretty much scratch and your job is to figure out what to assemble and get working first that will help you to do the next and build stuff up from there.
One thing is we've got lots of computer cycles to spend. So I'm comfortable now, as the pejorative saying goes, pissing away cycles to get something done cleanly.
I'm not a big reader – I'm very much of a doer. If I have a flaw, it's that I will often do my own of X, Y, or Z rather than reading the literature and knowing about it.
It isn't that young people learn that much faster; it's just they have more time.
I don't believe in putting comments beside everything. And I kind of feel like the better a language is, the less you need comments.
I feel like an artist when I'm working because I have this idea in my head and I just want to make it real. I imagine a sculptor having the same feeling, bringing a piece to life.
Often, reading about famous people, the side of it that I'm interested in is, how do they make their life work? All the things that weren't their passion, and how did they deal with that, and with their family, and with their finances, and balancing that. Or did they just hole up and say, "To hell with everything else", and let it just come crumbling down until they had their work done?
Music is kind of interesting because on the spectrum of formality it falls between natural languages and computer languages. It's more formal and structured than a natural language, but it doesn't have nearly the structure or formality of a computer language.
If you have a situation where you have something that's operating in multiple domains and the domains don't inherently have a lot of coupling or interaction with each other, that's a good place to put a pretty strong software boundary.
My belief is still, if you get the data structures and their invariants right, most of the code will just kind of write itself.
The difference is that the principles for dealing with algorithmic problems are based a lot more directly on 5000 or 10000 years' worth of history in mathematics. How we go about programming now, we don't have anything like that foundation to build on. Which is one of the reasons why so much software is crap: we don't really know what we're doing yet.
The further down in the plumbing the software is, the more important it is that it be built by really good people.
There has to be something a little wrong with you for you to be a really good programmer. Maybe "wrong with you" is a little too strong, but the qualities that make somebody a well-functioning human being and the qualities that make somebody a really good programmer – they overlap but they don't overlap a whole heck of a lot.
Software is a discipline of detail, and that is a deep, horrendous fundamental problem with software. Until we understand how to conceptualize and organize software in a way that we don't have to think about how every little piece interacts with every other piece, things are not going to get a whole lot better.
Requirements always change, they always are going to at least attempt to change in directions you didn't think of.
The reason I don't program in Lisp anymore: I can't stand the syntax. It's just a fact of life that syntax matters.
I had this little epiphany that the reason that I was having trouble finding another software project to get excited about was not that I was having trouble finding a project. It was that I wasn't excited about software anymore.
All of a sudden I had the feeling that the way – well, not the way to change the world for the better, but the way to contribute something to the world that might last more than a few years was to do music. That was the moment when I decided that I was going to take a deep breath and walk away from what I'd been doing for 50 years.
I could never be a teacher because you end up teaching your class over and over and over. I could never do that. But I love the teaching: the hard work of a first class, the fun of the second class. Then the misery of the third.
I was sort of incorrigible, to be honest. I suspected that I would eventually get fired, but it didn't bother me. We were supposed to be doing basic research but there was some basic research we should be doing and some basic research we shouldn't be doing. And just coming out of the ashes of MULTICS, operating systems was one of those basic research things we shouldn't be doing.
Modern programming scares me in many respects, where they will just build layer after layer after layer that does nothing except translate.
I usually write down data structures before I write down code.
I'll throw away code as soon I want to add something to it and I get the feeling that what I have to do to add it is too hard. I'll throw it away and start over and come up with a different partitioning that makes it easy to do whatever I wanted to do. I'm really quick on the trigger for throwing stuff out.
If it's part of a system or a library or something that's meant to be published, then I'll take the time to document it. But otherwise, no.
In those days you actually got the circuit diagrams of the machines, and we actually found the bug in the circuit diagrams. Then we just called DEC and said, "Connect that wire and that wire."
I think in almost any language you can write fragile code. My definition of fragile code is, suppose you want to add a feature – good code, there's one place where you add that feature and it fits; fragile code, you've got to touch ten places.
It [C++] certainly has its good points. But by and large I think it's a bad language. It does a lot of things half well and it's just a garbage heap of ideas that are mutually exclusive. Everybody I know, whether it's personal or corporate, selects a subset and these subsets are different. So it's not a good language to transport an algorithm – to say, "I wrote it; here, take it." It's way too big, way too complex. And it's obviously built by a committee.
What makes a program beautiful? - That it is a simple straightforward solution to a problem; that has some intrinsic structure and obviousness about it that isn't obvious from the problem itself.
The way I would approach understanding a new language or a new implementation of some very complex problem would be to take a program from somebody that I knew was a great programmer, and read it.
A piece of our challenge is to make computing, and all that it enables, accessible to everyone.
Almost the only thing I remember about high school is learning to program.
So I got this reputation – I fixed these mysterious bugs that nobody else could fix. Fortunately, they never asked me what the bug was. Because the truth of the matter is if they'd have asked, "How did you fix the bug?" my answer would have been, "I couldn't understand the code well enough to figure out what it was doing, so I rewrote it."
Classes can give you a lot of stuff, but in the end programming is a craft you have to perfect by plying it.
I learned how to program in order to make things happen.
The only way to make a program testable is to think about that before you write the first line of code.
If you're looking at a piece of code and it looks very hard – if you can't understand what this thing is supposed to be doing – that's almost always an indication that it was poorly thought through. At that point you don't roll up your sleeves and try to fix the code; you take a step back and think it through again. When you've thought it through enough, you'll find out that it's easy.
Source code is for people, not for computers. Computers don't care.
I don't put a lot of comments in my code because I think you should be writing your code so that it is readable and your algorithms and thoughts are clear in the code.
Programmers are the worst optimizers in the world. They always optimize the part of the code that's most interesting to optimize, and almost never get the part of the code that actually needs optimization.
I'm glad I can have a little bit of repute as having once been a good programmer without having to actually demonstrate it anymore, because I don't think I could.
When I wrote TeX originally in 1977 and '78, of course I didn't have literate programming but I did have structured programming. I wrote it in a big notebook in longhand, in pencil.
I think programming is a lot like religion; people have their beliefs. Some people like to force their beliefs on others. Others say, you know, here's what I think; I can't prove that this is the best thing, but it sure works for me. Then you hope that other people will try it and come to the same conclusion. But I don't like going out and telling people what they ought to believe.
The first rule of writing is to understand your audience – the better you know your reader the better you can write, of course. The second rule, for technical writing, is say everything twice in complementary ways so that the person who's reading it has a chance to put the ideas into his or her brain in ways that reinforce each other.
Only two percent of the world's population is born to be super programmers. And only two percent of the population is born to be super writers. And Knuth is expecting everybody to be both.
To me the idea of the right kind of a program is something that matches the way I think as closely as possible rather than something that matches the machine as closely as possible. I have to find the way to do the conversion, but my source text tries to stay closer to my brain than to the machine.
The problem is that coding isn't fun if all you can do is call things out of a library, if you can't write the library yourself. If the job of coding is just to be finding the right combination of parameters, that does fairly obvious things, then who'd want to go into that as a career?
I've been a nitpicker all my life. So if I can get my kicks out of finding errors then I just have to make sure that I forget that I was the author of the program. I try to imagine that somebody else was the author.
If we restrict ourselves to the things that are really easy, then that's not satisfactory because our appetite is always to push the boundary and go until it gets to something we can barely do. And once we've got to there, then we're going to want to push that boundary and so on.
Inevitably we're going to have bugs unless we decide we're never going to write anything that stretches our capabilities.
There's the change that I'm really worried about: that the way a lot of programming goes today isn't any fun because it's just plugging in magic incantations – combine somebody else's software and start it up. It doesn't have much creativity. I'm worried that it's becoming too boring because you don't have a chance to do anything much new. Your kick comes out of seeing fun results coming out of the machine, but not the kind of kick that I always got by creating something new. The kick now is after you've done your boring work then all of the sudden you get a great image. But the work didn't used to be boring.
The more you learn to read other people's stuff, the more able you are to invent your own in the future, it seems to me.