Изменить стиль страницы

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.

Seibel: 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?

Seibel: 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.

Seibel: 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.

Seibel: 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.

Seibel: 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.

Seibel: 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.

Seibel: 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.

Seibel: 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?

Crockford: Yeah, definitely, because I believe I’m using the only correct style and everybody else got it wrong! I think Thompson and Ritchie did the world a disservice by not defining the pretty-print presentation for C. Saying, “This is how we do it, but you can do it some other way,” has had a huge toll on humanity, and it will probably continue to always have one.

Seibel: So your preferred style is K&R?

Crockford: Yeah, I think they got it right. Their initial style is right. Particularly in JavaScript. JavaScript does semicolon insertion, and so there are places where the meaning of a program will change in a drastically bad way if you put the braces on the left instead of on the right. It turns out the K&R style is not subject to that problem, but the flush style is.

So I can argue in the case of JavaScript, there absolutely is a correct way of placing the braces. In other C-flavored languages I can’t make that same case. Some people like to have their braces flush and I’ve seen people argue for hours about which way is right, and none of the explanations make any sense on either side, because what they’re really arguing is, what I used in school, or what I used at my first job, or the style that’s used by someone who impressed me, now looks right to me and everything else looks wrong.

It’s similar, I suppose, to an argument about, should we be driving on the left side of the street or the right. Ultimately there’s not a good case for doing it one way or another. If you live on an island, you can do it the wrong way and it doesn’t matter, but ultimately the community benefits if we can all figure out how to drive on the same side.