Crockford: Yeah, go through it line by line, and you’ll be doing commentary on it. This is what’s supposed to be happening here. If we have time, we’ll go line by line.
Seibeclass="underline" Do you find that you have to teach people how to do code readings? I can imagine it’d be hard to find the right balance of being critical enough to be worthwhile without making the code’s author feel personally attacked.
Crockford: Yeah, it requires a lot of trust on the part of the team members so there have to be clear rules as to what’s in bounds and what’s not. If you had a dysfunctional team, you don’t want to be doing this, because they’ll tear themselves apart. And if you have a dysfunctional team and you’re not aware of it, this will reveal it pretty quickly. There’s a lot that you can learn, a lot that’s revealed by this process. It feels unnatural at first, although once you get into the rhythm of it, it feels extremely natural.
Another aspect is writing your code such that it can be read. Neatness counts, as it turns out, and style is important. And all of those things will increase the quality of the code base going forward and increase the competence of the programming community.
Seibeclass="underline" What makes code readable for you?
Crockford: It happens at a number of levels. The simplest is just being consistent in the presentation so you always indent everything properly; you have white space in all the right places. One habit that I still struggle with, something I learned back in the Fortran days, is I tend to use too many oneletter variable names, which I believe is a bad thing. And I’m trying really hard to break it, but it’s difficult—it’s still something I struggle with.
Seibeclass="underline" How hard is it? Do you write the code and then you come back later and say, “Oh, look at all these one-character variable names.”?
Crockford: I think in terms of one letter. Also in JavaScript, there’s an indefensible efficiency argument that you’re actually paying for the download cost of those extra characters, and so you can make programs smaller by making your variable names smaller.
Seibeclass="underline" There are tools for that, right?
Crockford: Well, you can gzip it and that pretty much takes it all out, so I have no defense. When I’m going back through my old code and I see the names are too short, if I have time, I’ll change them. Some things, like my loop counters, will probably always be i. I don’t think I’ll ever fix that, but there are a lot of others that are just inexcusable.
That’s the first level, the grammatical stuff. It’s similar to writing in English or any language, getting the punctuation right, getting the capitalization right, putting the commas in the right place. Then you start looking at higher-level things like how you structure the sentences and where you break the paragraphs. In a programming language, it takes the form of how do you decompose the problem into a set of functions or a set of classes?
Seibeclass="underline" What are the concrete things that programmers should focus on to make their code readable?
Crockford: The subset idea is really important, especially for JavaScript because it contains so many bad features. But it’s true for all languages. When I was a journeyman, I would read the language manual and I would understand every feature. And I would figure out how to use them all. And I’d use them all all the time. It turns out a lot of them were not well thought through.
I’m thinking back to Fortran now, but it was true in all languages. Sometimes language designers get it wrong. C has a whole bunch of errors in it, from my perspective now.
Seibeclass="underline" For instance?
Crockford: Like the switch statement having fall-through be the default was wrong—they shouldn’t have done that. ++ has huge security problems—it encourages you to be way too tricky, to try to do too much in one line. In that compulsion to do it in one line, you make code which is hard to understand and which is likely to lead to things like buffer overrun errors. So most of the security problems that we’ve seen in operating systems over the last few years are a consequence of ++.
In my programming style now I don’t use ++ anymore, ever. I can make the case that it’s good to use it here and it’s bad to use it there but it’s hard for me to find the good pieces and the bad pieces in my code.
Seibeclass="underline" Couldn’t one argue that the security problem with ++ really has nothing to do with ++ but with unchecked array bounds or raw pointers? It isn’t a security risk in Java because if you ++ off the end of the array you just get an exception.
Crockford: Yeah, it’s certainly less dangerous in Java. And that danger doesn’t exist at all in JavaScript because it doesn’t have arrays. But even so, I found that the quality of my code got better when I stopped doing it, just because it invited me to write one-liners and that’s usually a bad idea.
Another example of that is the continue statement. I have never seen a piece of code that I could not improve by taking the continue out. It makes certain kinds of complicated structures easier to write. But I found that I can always improve the structure if I can find a way to factor it out. So as part of my personal discipline, I don’t use continue ever. If I see a continue in my code, then I assume I haven’t thought it through carefully.
Seibeclass="underline" How do you read code you didn’t write?
Crockford: By cleaning it. I’ll throw it in a text editor and I’ll start fixing it. First thing I’ll do is make the punctuation conform; get the indentation right; do all that stuff. I have programs that can do that for me, but I find doing that myself is more efficient in the long run because it gets me more acquainted with the code. Morningstar taught me to do this. He’s brilliant at refactoring other people’s code and that’s the approach he takes and I find it works.
Seibeclass="underline" Have you ever found that code that was, at that level, a mess, then you cleaned it all up and discovered it was actually good code underneath?
Crockford: I’ve never actually seen that. I think it’s really difficult to write good code in a sloppy manner. By good code, I mean it’s going to be readable. At one level, it doesn’t matter what it does to a machine if I can’t figure out what it does, so it might turn out that the code is amazing in terms of its efficiency, or its compactness, or some other metric which I don’t care about.
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. So I think it’s probably not good code and they probably made the wrong trade-offs if the code turned out to be in the state that it’s not easily readable.
Seibeclass="underline" What about in the inner loop of the inner loop where it’s just got to be blazing-fast? Can all code be readable or are there times when you must sacrifice readability to gain efficiency?
Crockford: I suppose, but I would write a novel on both ends of that and explain this is why we’re doing what we’re doing. Usually that gets left out. I also see a lot of folks struggling to try to make stuff fast in situations where it absolutely doesn’t need to go fast. They’re unaware of how their own program is spending its time and so they’re optimizing things which don’t require optimization and which will never be big enough going through that path to ever make any difference so there’s no reward, no benefit at all, for having done that optimization. All the optimization did was introduce cruft. I see a lot of that.
Seibeclass="underline" In curly-brace languages, there are endless religious wars about what’s the proper place to put the braces, and people argue that one style or the other makes it easier to read. Is part of what you’re doing when you “clean up” code just putting it in the form that’s easy for you to absorb?