Êíèãà: Coders at Work: Reflections on the craft of programming
Douglas Crockford
Douglas Crockford
A senior JavaScript Architect at Yahoo!, Douglas Crockford has been a programmer since the early ’70s when he took a Fortran course in college after being unable to get studio time for his major in television broadcasting. Over the course of his career, he has combined computers with media in various ways at places like Atari, Lucasfilm, Electric Communities, and now Yahoo!
Crockford is, by nature, a simplifier and a tidier. He invented JSON, the data interchange format widely used in Ajax applications, because he found XML too complicated. His recently published book, JavaScript: The Good Parts, argues that JavaScript is actually quite a nice language if one avoids certain features. When I talked to him he stressed the importance of subsetting as a way of managing complexity and described a code-reading process he uses that starts with simply tidying up the code.
At the time of our interview, Crockford had become well known as an outspoken critic of the proposed ECMAScript 4 (ES4) revision to the ECMAScript (JavaScript) language standard, on the grounds that it was too complex. He was in favor of a more modest proposal labeled ES3.1, and since then he and the other ES3.1 advocates have largely prevailed—ES3.1 has been renamed ES5, and the ES4 effort has been officially abandoned.
Crockford and I talked about what he disliked about the ES4 proposal, the importance of code reading as a team activity, and how to move the Web forward despite the legacy of existing systems.
Seibel: How did you start programming?
Crockford: I went to San Francisco State University. I went there because they had a really good television program. My first year I couldn’t get into the studio so I looked for other things to take and sort of as a fluke I took a Fortran class in the math department. And it turned out I was really good at it so I took the second-semester class.
That was ’71, ’72. It was punch cards in the basement of the library. Timesharing had just come to the school. At San Francisco State we didn’t have a strong engineering department that owned all the computers. Instead they got distributed all over the school. Natural sciences had a lab; school of business had a lab; school of education had a lab; and humanities had a lab. Which was really interesting in that you had all these disciplines all playing with computers.
I went to work first in the science lab and then in the humanities lab. So I’d have people coming in who were economists or psychologist or geographers—they were the most interesting people. I’d learn about the problems that they were working on and 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.
Eventually I got into the studios and did all the TV stuff and that was fun but in the end I decided to go the computer way. But all along I spent a lot of time thinking about the two things together. I anticipated a lot of what would become multimedia and now digital media, and at various times in my career I’ve gone back and done the media part and then returned to the programming part.
Seibel: So you started with Fortran and discovered that you were good at it. Was there anything that drew you to programming other than, “Oh, I seem to be good at this.”?
Crockford: That’s all it was. It was my first semester, and I had to take a math class and I had picked one of those at random and it happened to have Fortran in it. So I didn’t go into it intending to learn how to program. It was just what happened.
Seibel: What was the first interesting program you remember writing?
Crockford: That’s going way back. I think it was a program I wrote to disassemble the runtime of the Fortran system on the timesharing system I was using. By doing that, I was able to read how that system worked and taught myself a lot about programming based on that model, something which would not ordinarily have been published.
Seibel: What do you think is the biggest change in the way you think about programming compared to back then?
Crockford: There was a period of maybe a decade where efficiency was really, really important. I guess it was in the early microprocessor era when memory was still really small and the CPUs were still really slow. We’d get down into assembly language in order to do things like games and music to make it fit and to make it fast. Eventually we got over that, so today we’re writing big applications in JavaScript that run in a browser. It’s such a profoundly inefficient environment compared to the stuff that we used to do, but Moore’s Law sort of made it all OK.
Seibel: And is there anything that you regret about the path that you took learning to program?
Crockford: There are some languages that I was aware of that I never got a chance to use. I’ve read a lot about APL and I understand why it lost, but it was really neat and I never spent any time with it and that was unfortunate. There are other languages like that, where I’m aware of them, I’ve read what I can about them, but I never got a chance to actually think in them.
Seibel: So you actually ended up doing your degree in broadcasting; after that what did you do?
Crockford: I started a master’s program in educational technology. But I felt like I was so far ahead of where the program was that I was just wasting time. I left that after about a year and went to work at SRI in Menlo Park, as a researcher. Then I went to a company called Basic Four, which was making small business minicomputers and spent a lot of years there. I developed a word-processing system for them and started doing some research into portable machines and PCs. I tried to push that company into PCs; I bought the first PC in the company and left it open on my desk so that the engineers could come look at it and see what IBM had done, but ultimately I couldn’t change the culture there—they were pretty set in what they were doing.
Then one Christmas, maybe it was Christmas of ’81, I bought an Atari 800. I went to the computer store and there was an Apple II and an 800 and the 800 looked to be snazzier so I got that one. I thought that I’d write a word processor on it or a programming language for it. But the 6502 was just not up to doing anything. So I’d spent two thousand dollars for the thing—what can it do? Well, obviously it can do games. So I started writing computer games and I sold one to Atari and then got an offer to work in their research laboratory in Sunnyvale. That was the research lab that Alan Kay had started, his first thing since PARC. So I went there and it was great. I was there for two years and watched the company melt down. But I managed to do some interesting work there. Worked with some really good people.
Seibel: Had you ever been a game aficionado before that?
Crockford: I’d thrown some quarters at Space Invaders and Pac-Man. I liked the games; I wasn’t hard-core. The interesting thing about games for me was it was another place where television interacted with computers. It was the first place where the public got to participate in that interaction. I thought that was really interesting.
Seibel: After Atari melted down, what next?
Crockford: Then I went to Lucasfilm and was there for eight years.
Seibel: And Habitat started while you were there.
Crockford: It sure did. A friend of mine, Chip Morningstar, started that project. He invented the avatar; he invented the graphical virtual world. He did all that stuff first. It ran on Commodore 64s and off-peak x25 networks. Just amazing foresight in the design of that thing—he got so much right, it was amazing. I was sort of a spectator. I saw them doing it and encouraged them. But I can’t take any credit for what they did.
Seibel: And then you went with them to found Electric Communities, which built upon those ideas?
Crockford: Right. Morningstar and Randy Farmer left Lucasfilm to start a company called the American Information Exchange, which took their idea of a social server and applied it to the idea of online markets. Brilliant idea, but ahead of their time. Had they been a little bit later, they could have been eBay.
Then we got the idea of well, let’s do that again and come up with a common platform which does the entertainment thing and the social thing and the business thing and the commercial thing and everything and we’ll do the platform for the whole world. And we had some ideas about how to make it fully distributed so that there is no single server—that it all spreads over the Net. And we would come up with security models that would allow it to be fully decentralized. It was a really powerful idea and that was the idea behind Electric Communities.
Seibel: And that’s where the first versions of E came from.
Crockford: Right. We needed a secure programming language to develop the platform and the applications in. And our first attempt at that was something called Joule which was being developed at another company called Agorics. Joule was an actor language and was pretty odd in the way that it did things—it was brilliant but unconventional.
We had concerns about Joule. Were we going to be able to get people to use this language; is it too freaky? Then we came up with the idea of E, which was taking the core actor concepts out of Joule and reimplementing them on top of Java.
Seibel: Did E ever have any adoption by anyone other than its inventors?
Crockford: Not the original language. The old E was a Java dialect. We had all sorts of problems with Sun about that. We then came up with an E scripting language that was lighter but had similar properties. And that is the language which is now called E.
We developed that language at Electric Communities but I don’t think we ever made use of it. But at one point we decided that we weren’t using it, but it was good stuff so we spun it out and I’m really happy to see that it survived.
One of the things that was good for me in being at Electric Communities is it taught me to think in terms of closures. So when I started doing web stuff I looked at JavaScript and said, “There’s something familiar about this.” Because a lot of JavaScript’s heritage comes from Scheme but you look at the documentation and there’s nothing there that tells you that there are closures in the language. So I kind of discovered it by accident and went, “Whoa! This is great.” And I’ve been promoting that idea that you can actually do serious programming in this silly little language.
Seibel: So that sort of brings us to the recent controversy about ECMAScript 4. I gather that you like the simplicity of the ES3 version of JavaScript.
Crockford: Well, ultimately, 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 reeducation 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.
JavaScript, purely by accident, has become the most popular programming language in the world. There are more JavaScript processors in the world than any other language by far. And for all of its problems with its security model, JavaScript is the only language where you can write code and run it on any machine.
And if that weren’t enough, it’s now being embedded in a lot of applications. Most of the Adobe applications have JavaScript in them so you can script them locally. And other applications as well. So it’s become hugely popular.
The problem with the language is that it was rushed to market way too fast and standardized way too fast. So most of its defects are not in the current implementations—they are in the specification. The standard says do this incorrectly. Which is appalling. But that’s the state of it. It got frozen in 1999 and then should have gone into neglect and died. But instead, by accident, Ajax happened and suddenly it’s the world’s most important programming language.
So now we’re thinking that we need to fix it. But the time to have fixed it should have been in 2000. But it didn’t get fixed then, back when everyone was paying no attention to it. Now it’s huge.
There’s another thing that’s odd about JavaScript in the web context: If you’re doing a server application or a desktop application or an embedded application, you get to choose not only the language but which specific compiler you’re going to use, which specific runtime you’re going to use. You don’t get that choice in JavaScript. You have to run on everything that’s out there.
Because we have to run on everything, bugs don’t get fixed. If a browser maker ships a bug and goes, “Oops, we screwed up,” and the next month they ship another one, we cannot depend on all of their users doing the upgrade. The mainstream, once they get IE installed on their machine, that’s it; they don’t upgrade. Those bugs stay there for years.
Seibel: So that’s the current situation. Yet you want the Web to be a better platform for developing applications. If we can’t fix the problems we have unless all the browsers fix it and even that doesn’t help, we’re just stuck. What’s the way forward?
Crockford: That’s the thing I struggle with. I can see the ideal. I know what it needs to be. And I know where we are and I can see all the obstructions in the way. And so I’m trying to figure out how do we take this forward. We’re in a trap, in a sense, in that we have developed these huge systems—I’m more concerned with the economic systems and the social systems, but also the technological systems—that are dependent on this system which was not thought through very well.
The worst feature of JavaScript, without question, is its dependence on a global object. It doesn’t have linkers, it doesn’t have any kind of information hiding between compilation units. It all gets dumped together into a common global object. So all the components see everything else; all the components have equal access to the DOM; they all have equal access to the network. If any script gets onto your page it can go to the server and represent itself as your script and there’s absolutely no way the server can tell the difference.
It has access to the screen; it can go to the user and represent itself as your script and the user can’t tell the difference. All of the new antiphishing things that they’re putting in the chrome don’t work if the page came from your server and all scripts come with the same authority no matter where they came from.
But it’s even worse than that because there are other ways that script can get onto your page. The architecture of the Web has several languages in it—there’s HTTP, there’s HTML, URLs are a language, there’s CSS, and there’s the scripting language. They’re all in there and they can all be embedded in each other and they all have different quoting and escaping and commenting conventions. And they are not consistently implemented in all of the browsers. Some of them are not specified anywhere. So it’s really easy for an evildoer to take some script and put it in a URL, put it in a piece of style and put that in some HTML and put that in another script, and so on.
Seibel: Those are the classic cross-site scripting attacks, taking advantage of bugs in the browser.
Crockford: Right. That’s horrible; we have to fix that—it’s intolerable that we keep going this way.
On top of that we’ve discovered mash-ups. And mash-ups realize something that we’ve been trying to do in software for 20 years: to have interesting reusable components that we can snap together like LEGO and make new applications out of, instantly. And we’re doing that stuff in mash-ups and it’s brilliant, where you can take something from Yahoo! and something from Google and something of yours and something of someone else’s and put them all together and make an application, and it’s great. And it all happens on the browser, right in front of your eyes. Except that each of those components has access to the same stuff. So now we are intentionally creating XSS exploits. And the browser’s security model did not anticipate any of this goodness and does not provide any way of allowing for cooperation with mutual suspicion. The whole Web is built on one mistake after another. We have this big pile of accidents.
Seibel: So given all that, is the cost of the ES4 effort just the opportunity cost, that everyone is going to spend time thinking about that instead of some way to fix these problems?
Crockford: Right. It’s solving the wrong problem. It’s solving the problem that people hate JavaScript. And I can appreciate Brendan Eich’s position there because he did some brilliant work but he rushed it and he was mismanaged and so bad stuff got out. And he’s been cursed and vilified for the last dozen years about how stupid he is and how stupid the language is and none of that’s true. There’s actually brilliance there and he’s a brilliant guy. So he’s now trying to vindicate himself and prove, I’m really a smart guy and I’m going to show it off with this language that has every good feature I’ve ever seen and we’re going to put them all together and it’s going to work.
I don’t think that’s the problem we need to be solving right now. I think the problem we need to be solving is: The Web is broken and we need to fix it. So we need to figure out a way to go forward. And my biggest objection with what Brendan is trying to do is it’s a distraction.
I’m looking at this stuff incrementally. If we can get a module; if we can get a choice of programming language, we’ve gone way forward. We’re still not done yet, but we’re in much better shape than we are now. Then there are things like Caja and ADsafe which are trying to do that using today’s technology. We can’t wait.
What ADsafe does is it creates a safe subset of JavaScript. So it disallows access to anything that’s global and anything that’s dangerous. And it turns out there’s still a useful language in that subset. Because all the lambda power is there. And lambdas can do a lot. So it’s an unconventional language because it doesn’t let you use prototypes in the way we have up until now. But it’s a full lambda language, so hugely powerful.
Seibel: Leaving aside that it may be solving the wrong problem, are there any bits of ES4 that you like, just from a language point of view?
Crockford: There are some bug fixes that are good that I think we should have. But there’s too much stuff in the language that hasn’t been tried. And our experience with ES3 is that once an error gets into the spec, it’s impossible to take it out. And we have no experience with this language. No one has ever written a big application with it.
It will be standardized and deployed before we know that it works. So I think we’re doing this way too fast. I’d be much more comfortable if we had multiple reference implementations and people doing useful applications with it and then go, OK, the language seems to work; now let’s standardize it, now let’s deploy it worldwide. I think we’re doing it all backwards.
Seibel: So Google’s GWT compiles Java into JavaScript. And other folks have played around with compiling other languages to JavaScript. Is that a path forward?
Crockford: It’s sort of interesting to see JavaScript turning into the universal runtime. That’s not a role we ever expected for it.
Seibel: But, as you said, it’s everywhere; it is the universal runtime.
Crockford: Which I think puts even more pressure on getting JavaScript to go fast. Particularly as we’re now going into mobile. Moore’s law doesn’t apply to batteries. So how much time we’re wasting in interpreting stuff really matters there. The cycles count. So I think that’s going to put more pressure on improving the quality of the runtime.
As far as GWT goes, and other transforming things, I’m really pragmatic. This environment is so hard to work in—if you can find something that works, then great. I’m fearful of using it myself because I worry about the abstraction leakage. If there’s a problem in your Java code or in GWT or in what it produces on the other side, you may or may not have a place to stand to deal with that. Particularly if you took the approach that you can afford to be completely ignorant about JavaScript because the language is hidden from you. Then you’re going to be in a world of hurt if anything goes wrong. I hadn’t heard of that happening to anybody, so, so far they appear to be doing it right. But there is that risk.
Seibel: What would you like to see happen with JavaScript?
Crockford: I think the best way to make JavaScript better would be to make it smaller. If we could just get it down to what it does really well and remove the features that add little or no value, it’s actually a better language. And I think we can take that approach to HTML; I think we can take that approach to HTTP and to CSS. I think all of the standards that we’re working with, we need to figure out what do they do right and what is it missing and refocus them, rather than just piling new features on top.
Seibel: Yet there’s often a tension between small, elegant jewels and sprawling, practical balls of mud. A small, perfect jewel is easy to understand and it doesn’t have warts but then you have to build more stuff on top of it to do anything. So everybody reimplements the same things over and over and that leads to a different kind of bloat and ugliness.
Crockford: But that’s not what’s happening. We have a number of Ajax library developers who are doing that and some of them are getting very sophisticated in their use of the language. And then the communities out there are building sloppy stuff on top of it and that’s working. So it’s not necessary for every application programmer to understand how to fully exploit lambda in order to take advantage of the lambda nature of the language. So we’re already doing that. We don’t need to abandon the language in order to fix that—that’s not where it’s broken.
Where we do have a problem there is that there are too many Ajax libraries. That was a consequence of the fact that JavaScript is so powerful and the need is so profound and that they’re easy to make. So for a while everybody was making them. I’ve been expecting that we’re going to have a shake-out but it hasn’t happened yet. So we still have a whole lot of libraries. So we have an alternative problem now—because there are so many libraries to choose from, developers don’t know which one to use. I think there will be a shake-out eventually.
One thing that we’re seeing now is that the Ajax libraries are converging. jQuery came up with a notation for using CSS selectors for getting a list of objects from the DOM and then providing methods for manipulating the objects en masse. And that turns out to be a really good idea and it’s something that JavaScript does very effectively. There’s an inefficiency there in that the interface to the DOM is horrible but they hide it all. They’ve really simplified the programming model—it’s brilliant.
So everybody’s doing that now—we’re seeing feature convergence. Which makes the problem even harder for the user community because it makes it harder to decide which library to use because they’re all becoming more similar. But eventually they’re going to coalesce down to a couple, maybe one. I had been predicting that one of the winners was going to be Microsoft with their Atlas framework, just because Microsoft is always one of the winners. But they don’t appear to be getting traction. The open frameworks seem to be doing much better. So I’m expecting one or two of the open frameworks will ultimately win.
Seibel: These days you’re a JavaScript architect and evangelist here at Yahoo!, so part of your job, presumably, is to tell Yahoo! JavaScript programmers, “Here’s how you should do it.” Does your job also cover general good design practice and good coding practice?
Crockford: One of the things I’ve been pushing is code reading. 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. There’s a tendency in project management just to let the programmers go off independently and then we have the big merge and if it builds then we ship it and we’re done and we forget about it.
One of the consequences of that is that if you have weak or confused programmers you’re not aware of their actual situation until much too late. And so the risks to the project, that you’re going to have to build with stuff that’s bad and the delays that that causes, that’s unacceptable. The other thing is that you may have brilliant programmers on the project who are not adequately mentoring the other people on the team. Code reading solves both of those problems.
Seibel: Can you talk a bit about how you conduct a code reading?
Crockford: At each meeting, someone’s responsible for reading their code, and they’ll walk us through everything, and the rest of us will observe. It’s a really good chance for the rest of the team to understand how their stuff is going to have to fit with that stuff.
We get everybody around the table; everybody gets a stack of paper. We also blow it up on the screen. And we all read through it together. And we’re all commenting on the code as we go along. People say, “I don’t understand this comment,” or, “This comment doesn’t seem to describe the code.” That kind of stuff can be so valuable because as a programmer you stop reading your own comments and you’re not aware that you’re misdirecting the reader. Having the people you work with helping to keep your code clean is a huge service—you find defects that you never would’ve found on your own.
I think an hour of code reading is worth two weeks of QA. It’s just a really effective way of removing errors. If you have someone who is strong reading, then the novices around them are going to learn a lot that they wouldn’t be learning otherwise, and if you have a novice reading, he’s going to get a lot of really good advice.
And it shouldn’t be something that we save for the end. Back in the old days, we would schedule a code reading just as we were finishing a project and usually it would be canceled because we were late. I now believe that code reading should be happening all the time throughout the life of the project. That’s something that took me a while to figure out but there are so many benefits that come from that.
For one thing it makes it easier to track the project, because we can actually see what progress people are making. And we can see much sooner if they’re going off the rails or not.
I’ve managed projects where we’re up against a deadline and we had people saying, “Yeah, I’m almost done,” and then you get the code, and there’s nothing there, or it’s crap, or whatever, and they’re nowhere close to done. In management, those are the experiences you hate the most and I think code reading is the best way of not getting trapped like that.
Seibel: So say we’re doing a code reading of some of my code. I bring printouts and we put it up on the screen. Then what? Do I literally read it out loud?
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.
Seibel: 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.
Seibel: 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.
Seibel: 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.
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.
Seibel: So if you changed jobs and went somewhere where they programmed C or Java in a different style than you prefer, would you say, “Well, I’ll switch and I know that after a little bit, I’ll be happy to see this style”? Or would you just not take the job?
Crockford: Maybe that’s something that people should look at—what is the house of style here? Are we on the left or the right? And maybe not go work at a place that gets them on the wrong side. It does take on a Dr. Seuss quality where you get really upset about whether you’ve got a star on your belly or not. Ultimately you have to embrace the house style and you hope that the people who put the house style together knew what they were doing. They probably didn’t; maybe it doesn’t matter. It’s more important that everybody be on the same page.
Seibel: So when you’re reading code you start with a typographical cleanup, how deeply or dramatically do you refactor things?
Crockford: I’ll rearrange code so that everything is declared and set up before it’s called. Some languages give you a lot of flexibility around that so you don’t have to. I don’t want that flexibility.
Seibel: So you want no forward references?
Crockford: Right, or if there is a forward reference, I want it to be explicit. I don’t want code to come in any random order unless I’m doing a literate programming thing in which I’m explicitly breaking the code in terms of a presentational order rather than the order that the language wants, and I like that a lot. But unless you’re actually using literate tools, you shouldn’t be doing that.
Seibel: In one of your talks you quoted Exodus 23:10 and 11: “And six years thou shalt sow thy land, and shalt gather in the fruits thereof: But the seventh year thou shalt let it rest and lie still” and suggested that every seventh sprint should be spent cleaning up code. What is the right time frame for that?
Crockford: Six cycles—whatever the cycle is between when you ship something. If you’re on a monthly delivery cycle then I think every half year you should skip a cycle and just spend time cleaning the code up.
Seibel: So if you don’t clean up every seventh cycle you may be faced with the choice of whether or not to do a big rewrite. How do you know when, if ever, it’s time for a big rewrite?
Crockford: Generally the team knows when it’s time. Management finds out a lot later. The team is getting beat up pretty regularly, making too many bugs; the code’s too big, it’s too slow; we’re falling behind. They know why. It’s not because they became stupider or lazier. It’s because the code base is no longer serving the purpose that it needs to.
It’s a really difficult thing for management to see, particularly managers who are not programmers. But even programming managers have trouble with this because you’ve seen that you’ve invested so much time to get to this point. And starting over means we’ve got to go all the way back to there and bring it up. And in the meantime we’re not going to be going forward on anything else and it’s just impossible. No, we go forward with what we have.
The fallacy is that it’s going to take that amount of time again, though there are counterexamples. You’ve got the second-system problem where people who’ve had some success are given a blank slate and allowed to do whatever they want. Generally, they will fail because they’ll be too ambitious, they won’t understand the limits. And you get nothing out of that. You have to have extreme discipline to say, “It’s not a blank slate; it’s reimplementing what we had here; it’s doing what we knew.”
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. Particularly if you’re using a classical methodology you’re having to do classification on systems that you don’t fully understand. And the likelihood that you’re going to get the classification wrong is high.
Seibel: By “classical” you mean using classes.
Crockford: Right. I’ve found it’s less of a problem in the prototypal world because you focus on the instances. If you can find one instance which is sort of typical of what the problem is, you’re done. And generally you don’t have to refactor those. But in a classical system you can’t do that—you’re always working from the abstract back to the instance. And then making hierarchy out of that is really difficult to get right. So ultimately when you understand the problem better you have to go back and refactor it. But often that can have a huge impact on the code, particularly if the code’s gotten big since you figured it out. So you don’t. So you keep bundling these new things on top of it to try to patch the problems that were in the original hierarchy and it gets cruftier and worse.
Seibel: But you do think that refactoring can work, if you take every seventh interval to do it? You don’t have to end up needing a big rewrite?
Crockford: I think it can work. Throw it out and start over should only be considered in the cases where you didn’t do that or you did it badly or something went wrong and you’ve got a code base that has become unworkable. And you can make a reasonable judgment that it will be faster to replace it than to fix it.
Seibel: What about the risk that you don’t fully understand what the code you want to rewrite actually does. Because any piece of code contains bits of embedded knowledge—little bits of cruft that are hard-won functionality that you don’t think of when you say, “Oh, we can just rewrite this.”
Crockford: That is a real problem. One of the reasons that we’re in the mess that we’re in is that the Web is so poorly specified. The specifications were incomplete and were largely misinterpreted and many of those misinterpretations have become part of the canon. So these systems are way more complicated than they should be due to those historical reasons. Working at that level, yeah, I have huge sympathy for that, that there is a lot of undocumented knowledge that is reflected in the code base.
Microsoft has a similar problem with their operating systems, in that they shipped crap for too many years and then they had to remain compatible with all the bad stuff that was based on the bad stuff that they had done. And so the constraints that puts on the design of their next system are just horrendous. So it’s really hard going forward with that. Ultimately they may find that they can’t go forward anymore either.
Those sort of specification errors are really, really hard. And we have them in the Ajax world. Most of our problems in the Ajax world are due to the differences at the browser level. Doing the cross-browser stuff is much harder than it should be because the Web is not specified well and because the implementations are so variable.
We’ve gotten a lot better at that over the last few years, particularly with the advent of the Ajax libraries. Most of them do a very good job—not a complete job yet—but a pretty good job of boosting the level of programming that you do. So we’re not having to deal directly with the browser guts; we have a sort of virtualized application layer that we can work on that is fairly resilient and pretty portable. We have one group here at Yahoo! which is primarily responsible for dealing with the pain that the browser causes. And when they do their job right, it makes it easier for all the other developers here. So that’s good.
Seibel: On the other hand, rewrites don’t always work out. You just mentioned the second-system effect and in one of your talks, you described seeing it in action as “heartbreaking.” When was that?
Crockford: It was at Electric Communities. We got together the smartest team of programmers I’ve ever seen assembled anywhere. And we had enough money and we were going to reimplement the stuff that Chip and Randy had already done and knew exactly how to do it. Except it was grander.
Seibel: So that was basically Habitat, redone.
Crockford: Yeah, we were going to redo Habitat except it was now going to be globally distributed. And it turned out to be really hard. We actually got it built but it was painful. Not something I’d like to do again.
Seibel: Would the advice you gave before—to be very disciplined about only reimplementing what you already understand—would that have been sufficient to head off the disaster?
Crockford: I think it could have helped. We didn’t think about it in stages properly. We didn’t have an incremental approach. Had we taken an incremental approach, I would have started with two parallel efforts. One, work out a secure distributed platform which doesn’t do anything but has the infrastructure for doing the messaging and the object management. Two, let’s rebuild Habitat. Knowing what we know, with modern languages, let’s just rebuild it.
Then the second phase would be, OK let’s merge them together. Can we hoist this one on top of that one and still have a working system? OK, now distribute it.
Had we taken that kind of incremental approach, I think we would have been very successful with it. But we tried to do all of those in one step and that was too hard.
Seibel: And you think you were led into trying to do it in one step because you knew big chunks of it.
Crockford: Because we were so smart and we had so much experience. We had it wired. Couldn’t miss. Programmers are optimistic. And we have to be because if we weren’t optimists we couldn’t do this work. Which is why we fall prey to things like second systems, why we can’t schedule our projects, why this stuff is so hard.
Seibel: Is programming getting easier? In the future will more people be able to do something that we would recognize as programming?
Crockford: My interest in programming is helping other people to do programming, designing a language or a programming tool specifically so that it’s more accessible to more people—the thing that got Smalltalk started. Smalltalk went in a different direction, but the initial direction was really attractive to me. How do we build a language specifically for children or how do we build a language specifically for people who don’t think of themselves as programmers?
Seibel: Is that because you think should everybody learn to program, at least a little bit?
Crockford: I think you have to. The world has been pretty much taken over by computers now and in order to defend yourself, or to be a full citizen, you have to have some understanding of how these things work.
Seibel: Some folks would also argue that learning to program teaches a way of thinking that’s important, like reading and math are different ways of thinking, and both important.
Crockford: I used to think so. I had these amazing insights when I started programming: everything became orderly, and I saw structures and things I had never seen before. I thought, “Wow, this is amazing. Everybody should learn how to do this,” because suddenly I was feeling a lot smarter. Except pretty quickly I’d find, talking to other programmers, that somehow they didn’t get it. Programmers are capable of completely misunderstanding the world in exactly the same way everybody else does. I was really sad to figure that out.
Seibel: Do you still enjoy programming as much as you always did?
Crockford: Oh, yeah.
Seibel: Do you think that programming is at all biased toward being young?
Crockford: I used to think so. A few years ago I had sleep apnea, but I didn’t know it. I thought I was just getting tired and old, and I got to the point where it was so difficult to concentrate that I couldn’t program anymore because I just couldn’t keep enough stuff in my head. A lot of programming is you keep stuff in your head until you can get it written down and structured properly. And I just couldn’t do it.
I had lost that ability and I thought it was just because I was getting older. Fortunately, I got better and it came back and so I’m programming again. I’m doing it well and maybe a little bit better now because I’ve learned how not to depend so much on my memory. I’m better at documenting my code now than I used to be because I’m less confident that I’ll remember next week why I did this. In fact, sometimes I’ll be going through my stuff and I’m amazed at stuff that I had written: I don’t remember having done it and it’s either really either awful or brilliant. I had no idea I was capable of that.
Seibel: I read somewhere where you said that literate programming, a la Donald Knuth, is a brilliant idea. Do you use literate tools?
Crockford: No. I’ve been thinking about it and I’ve been designing literate tools for some of the languages that I’m using but I’m currently not doing any literate programming.
Seibel: Is that just a tool-chain problem? If the tools existed you think you would write literate programs?
Crockford: I would. I think JSLint, for example, would be easier for me to maintain if I had written it in a literate style. The thing I like about the literate style is that you’re designing the program specifically for reading and I think that provides tremendous value to the program.
Seibel: What are the key features of a literate programming tool, as you see it?
Crockford: The principal thing that Knuth found or provided was the ability to write out of order. So if I’m concerned with a particular thing which touches code in a lot of places, I can collect all that code together and describe it together, and then the tool will distribute the details out to where it needs to go.
Another of the things he frees you from is the size of a function. Ideally, you want a function to be no bigger than a screen’s worth so that you can read it all at once. And if it doesn’t fit, then you’re making a lot more functions, and if the functions aren’t actually contributing anything to the structure of the program, they’re just introducing noise.
Knuth allows you to take each of the aspects of that function, which may be closely related—it might have good coherence but it’s just big; sometimes stuff is big—and he allows you to represent each of those collections of stuff with an extremely descriptive label and then say, “This function is:” and then list those labels. You could do that with functions, but it’s not quite the same and then you have to deal with communication between the pieces, and so on. So it’s introducing more structure which doesn’t exactly match the problem.
Ultimately I would like to see new languages designed specifically to be literate languages. Knuth has been very good at applying the idea to Pascal and C, but I’d really like to see a new language which is, from the bottom, designed to be used in that fashion.
Seibel: Have you read Knuth’s literate programs?
Crockford: Sure.
Seibel: How do you read them? Like a novel?
Crockford: Yeah, I read it like a novel. I tend to be reading his prose rather than his program, but I really like the way he lays it out and he writes really well, and occasionally he’ll slip a little joke in there. I enjoy reading his stuff.
Seibel: And what do you get out of it? So you’ve read TeX: The Program, and you get to the end. Now are you ready to go add features into TeX or do you just have an overall sense of wow, Knuth’s a brilliant guy?
Crockford: That’s a really good question. I’ve read TeX, but I didn’t read it with an intention that I wanted to modify TeX. I was just reading it to see what he had done. I had a particular interest in how he was doing linebreaking, so I read that part with particular interest, more to understand his algorithm than to understand how the code works so that I can modify it or reuse it. If I were reading it with the expectation that I was going to mess with the program, I’m sure I would’ve read it differently.
Seibel: Do you often read code, literate or otherwise, for fun?
Crockford: Yeah. There’s not much code out there that’s good enough that you could read it for fun. Knuth wrote some. Fraser and Hanson have a C compiler that is literate; it’s very good. But there are not a lot of examples of that yet. That’s kind of a shame. That could indicate that maybe literate programming has failed, because there aren’t very many examples of it.
Seibel: What about Knuth’s magnum opus, The Art of Computer Programming? Are you the kind of person who read it cover to cover, who dips into it for reference, or who put it on the shelf and never looked at it?
Crockford: All except the last one. When I was in college, there were a couple of months where I didn’t pay rent in order to buy copies of his books. And I read them and found jokes in them, like there’s a TUG joke in the index of Volume I. I have not been able to make sense out of all of it. There are places where he goes really a lot deeper than I can go, but I enjoy the books a lot, and I’ve also used them as reference books.
Seibel: Did you literally read them cover to cover, skimming over the math that you couldn’t understand?
Crockford: Yeah, the part when there are too many stars, I would read it very quickly. I tried to make familiarity with Knuth a hiring criteria, and I was disappointed that I couldn’t find enough people that had read him. 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.
Seibel: To read Knuth, it seems to me, you have to be able to read the math and understand it. To what extent do you think having that kind of mathematical training is necessarily to be a programmer?
Crockford: Obviously it’s not, because most of them don’t have it. In the sorts of applications that I’m working on, we don’t see that much application of the particular tools that Knuth gives us. If we were writing operating systems or writing runtimes, it’d be much more critical. But we’re doing form validations and UIs. Generally performance is not that important in the things that we do. We spend most of our time waiting for the user or waiting for the network.
I would like to insist that it’s absolutely necessary for people to understand this stuff, but it’s not. And maybe that’s why web programming has taken off and why it’s so accessible and why JavaScript works. This stuff really isn’t that hard. And most of the things that make it hard are unnecessarily hard. If we just cleaned up the platform a little bit, this work gets a lot easier.
Seibel: So there’s the nitty-gritty stuff that Knuth will teach you how to do and then there’s the big picture. Even if you clean up the platform, building big systems and designing them in a way that’s comprehensible will still be hard. How do you design your code?
Crockford: It’s not so much about writing the program as making iterations on the program’s survival. Generally the reason we’re doing software is because we know we’re going to have to change it and changing anything is hard because there’s a likelihood that, in changing it, you’re going to break it.
You can’t anticipate everything that’s going to be done with it but you try to build in enough flexibility that it’s likely to adapt to whatever you’re going to do. So that’s what I’m thinking. How do I not write myself into a corner too much? How do I give myself the flexibility to adapt as I need to?
That’s one of the things that I discovered I really like about JavaScript. Refactoring in JavaScript, I find, is really easy. Whereas refactoring a deep class hierarchy can be really, really painful.
For example, JSLint has transformed quite a lot since I started writing it in 2000, 2001. And its goals have changed significantly—it’s doing a lot of stuff now that I never thought it would do. And a lot of that’s because JavaScript is so flexible. I can fiddle with it and allow the program to grow without becoming sloppy.
Seibel: What makes it so much easier?
Crockford: I’ve become a really big fan of soft objects. In JavaScript, any object is whatever you say it is. That’s alarming to people who come at it from a classical perspective because without a class, then what have you got? It turns out you just have what you need, and that’s really useful. Adapting your objects… the objects that you want is much more straightforward.
Seibel: Presumably the problem, working with a class-based language, is that it’s too static—you’ve got a big class hierarchy and if you want to change that structure you’ve got to take it apart and put it back together. In JavaScript it seems the danger is that it can be too dynamic—you’ve stuck little kludges everywhere and the actual structure of your program is determined by lots of things that happen at runtime; there’s no static thing you can look at and say, “OK, this is the program and how it’s structured.”
Crockford: That is the scary part of it and it’s good to be scared because it is scary and it is real. It requires discipline. In most of the classical languages, the language is the thing imposing the discipline. In JavaScript you have to bring your own discipline.
Part of what I do to keep my code from falling apart is to be really rigorous myself in how I put it together because I know the language is not providing that rigor for me. So today I would not consider undertaking something as complicated as JSLint without JSLint. JavaScript does not scale very well on its own, but with that tool I become a lot more confident that I’m going to be able to keep it working.
Seibel: So the softness of JavaScript objects can be dangerous. But if you never availed yourself of the ability to augment objects, then you might as well just be writing classes in Java. Is there some way you think about structuring your JavaScript programs to take good advantage of the flexibility the language gives you?
Crockford: For me it was years of trial and error. When I started working with JavaScript, I didn’t read anything about it. I just started. I found a sample program, which was awful, and started fiddling with it until it worked more like the way I thought it should. So I began programming in the language, having no understanding about what the language was, or how it worked, or how you needed it to think about it.
I understand why people are frustrated with the language. If you try to write in JavaScript as though it is Java, it’ll keep biting you. I did this. One of the first things I did in the language was to figure out how to simulate something that looked sort of like a Java class, but at the edges it didn’t work anything like it. And I would always eventually get pushed up against those edges and get hurt.
Eventually I figured out I just don’t need these classes at all and then the language started working for me. Instead of fighting it, I found I was being empowered by it.
Seibel: When you’re designing software, do you prefer to think top-down or bottom-up or middle-out?
Crockford: All at once. That’s the thing about keeping the system in your head. Ultimately you need to divide and conquer and get it down into something you can manage. I find I’m on all parts of the problem and using all those techniques simultaneously. And I keep struggling with it until I become clear on what the structure is. Once you figure out what the structure is, then the rest of it falls out.
Seibel: How do design and coding relate for you? Do you start coding immediately and then iteratively refine it, or do you do something that’s separate from writing code?
Crockford: They used to be separate. They’re becoming more similar now. I used to work in a design language or a meta language—something semi-English, a little structured, which is more descriptive of what you’re going to write. But if I’m writing in JavaScript, that language has turned into JavaScript.
Seibel: What tools do you actually use for writing code?
Crockford: I use a little freeware text editor. It doesn’t do anything tricky. That’s about all I need. There is much less need of formal tools like you have in other languages. The browser just wants a source file, and so you send it a source file, and the compiler is built into the browser, so there’s really nothing to do. You don’t have a linker. You don’t have a compiler. You don’t have any of that stuff. It just all runs on the browser.
Seibel: You use JSLint, presumably.
Crockford: I do use JSLint. I use it a lot. I try to use it every time before I run a program, so if I’ve gone through and I’ve done some edits, I’ll run it through JSLint first before I run it.
Seibel: So you edit in your text editor, run JSLint on the program, and then run it in a browser. How about debugging?
Crockford: It depends on the browser. If it’s Firefox, then you use Firebug. If it’s IE, then you use the Visual Studio debugger. They’re both actually very good. We have surprisingly good debuggers in the browser.
I’ve used frameworks in which there were inspectors built out of DOM elements that could then go into objects, and open them up, and inspect through that set of frames. But I found I really don’t need that. Just a debugger is enough.
Seibel: Do you ever step through code just as a way of checking it when you’re not tracking down a specific bug?
Crockford: Only if I have something that’s really intricate. I’ll step through it as part of my testing, but generally I only step if I know I have problems.
Seibel: How about other debugging techniques, like assertions, or proofs. Do you use any of those? Do you think in terms of invariants?
Crockford: I like them. I was disappointed that Eiffel was not the winner in the object-oriented-language contest; that C++ won instead. I thought Eiffel was a much more interesting language and I liked the precondition/postcondition contract stuff that it did. I would like to see that built into my language, whatever language I’m using, but that’s another one of those ideas that hasn’t really caught on.
Seibel: What’s the worst bug you ever had to track down?
Crockford: It would’ve been a real-time bug. It might’ve been in a video game. We’ve got interrupts popping all over the place, and no memory management at all, and the program suddenly goes away and you don’t know why. That kind of stuff is really hard. And generally there wouldn’t be a debugger around either.
At Basic Four we had developed a word-processing terminal. It was a Z80-based terminal with a full-page display and 64K, which wasn’t nearly enough memory for a display that big. And it had a local network connection to our server where it would send up the pages.
And we had this problem where every once in a while the screen would go blank. We had this architecture in which we had a line of text and then it would have a stop code, and then the address of the next line, and a little DMA processor that would follow those links. And at some point a link would go away—there was some race that was happening.
From our perspective, looking at it logically, all of the links were good, but we hadn’t considered the real-time interaction with the DMA processor, which might not be looking at memory at the same time that we were. I just puzzled it out. I remember I was working at home that day and I was on the phone with my team and suddenly the lightbulb went on; I knew what the problem was and I was able to tell them how to fix it and we never had that problem again.
In my experience, the worst bugs are the real-time bugs, which have to do with interactions with multiple threads. My approach to those bugs is to avoid making them. So I don’t like threads. I think threads are an atrocious programming model. They’re an occasionally necessarily evil, but they’re not necessary for most of the things we use threads for.
One of the things I like about the browser model is that we only get one thread. Some people complain about that—if you lock up that thread, then the browser’s locked up. So you just don’t do that. There are constantly calls for putting threads into JavaScript and so far we’ve resisted that. I’m really glad we have.
The event-based model, which is what we’re using in the browser, works really well. The only place where it breaks down is if you have some process that takes too long. I really like the approach that Google has taken in Gears to solving that, where they have a separate process which is completely isolated that you can send a program to and it’ll run there. When it’s finished, it’ll tell you the result and the result comes back as an event. That’s a brilliant model.
Seibel: Have you ever been interested in formal proofs?
Crockford: I watched it closely during the ’70s, looking to see if they were going to come up with anything. And I didn’t see it paying off. Software is so complicated and can go wrong in so many ways.
Basically, software is the specification for how the software is supposed to work. And anything less than the complete specification doesn’t really tell you anything about how it’s ultimately going to behave. And that just makes software really, really hard.
Seibel: How do you test code? Are you, as they say these days, testinfected?
Crockford: I tend to be more ad hoc. That’s another place where I’m considering changing my style, but I haven’t accomplished that yet.
Seibel: There is a JsUnit, right?
Crockford: There is a JsUnit. Testing of UI code is really difficult because it’s really dependent on a whole lot of stuff, so breaking it down into units tends to be less effective. Also, I found because of the style that I’m writing in JavaScript, it doesn’t break in an orderly way into units the way classes do, so you can think about testing a class in isolation.
In JavaScript, testing a function in isolation maybe doesn’t make much sense because there’s the state that it needs in order to be interesting. I haven’t figured out a sufficiently useful way of testing units of JavaScript yet.
Seibel: In places that have separate QA groups, how should developers and QA groups work together?
Crockford: I’ve had companies where there was an antagonism between the development teams and the testing teams, which I thought was extremely unhealthy. There was this theory that you keep the two separate and one would rat out the other, basically. And I just think it’s a horrible model.
It worked much better when we put the two teams together and made the testers responsible for helping the developers to make their programs better, rather than ratting out the developers. It changed the way they reported and was much more effective. Also, cycling the developers into testing, so you weren’t exclusively one or the other.
The place where I found that to be most effective was taking testing, sort of, to the ultimate: going to visit customers. I did some of that early in my career and that was a great experience, having to go live with a customer for a week, helping them to install a new system, and helping them to work out the problems with using it.
It gave me a huge amount of insight into what it’s like to actually use our stuff and what I want to be doing for the benefit of the people who are going to be using my stuff. Going back afterwards, developers who had not had that experience all seemed arrogant to me in a way which was completely inexcusable. The lack of respect they had for the people who used our stuff was appalling and it was basically a consequence of their having never met those people.
Seibel: Do you consider yourself a scientist, an engineer, an artist, a craftsman, or something else?
Crockford: I think of myself as a writer. Sometimes I write in English and sometimes I write in JavaScript.
It all comes down to communication and the structures that you use in order to facilitate that communication. Human language and computer languages work very differently in many ways, but ultimately I judge a good computer program by its ability to communicate with a human who reads that program. So at that level, they’re not that different.
Seibel: And if it can communicate well to a human, you feel like the communicating-with-the-computer part will fall out?
Crockford: You hope so. Computers are arbitrary and not very smart, so you have to make special efforts to make sure that they get it. Because that’s so hard, it’s easy to overlook the other part, but I think it is at least as important.
Seibel: So Dijkstra had a famous paper, “On the cruelty of really teaching computing science,” that basically said computer programming is a branch of applied math. Do you agree?
Crockford: Mathematics is important in programming, but it’s just one of a lot of things that are important. I think if you overemphasize the math then you underemphasize stuff which might be even more important, such as literacy.
I mentioned I wanted to have the hiring requirement that they had to have read Knuth and I couldn’t do that because I couldn’t find enough people who had. The other thing I wanted was that they be really literate in whatever language they write to other humans. I want people who can write, because we spend a lot of time writing to each other. We’re writing email or documentation. We’re writing plans. We’re writing specifications. I want to know that the people on my team are capable of doing that, and that turns out to be a really difficult skill. So I would actually rather see people start as English majors than as math majors to get into programming.
Seibel: I think Dijkstra had another quote about that along the lines of, “If you can’t write in your native language, give it up.”
Crockford: I agree with that one.
Seibel: An aspect of programming that you seem to keep running up against is that while we are unbound by physical constraints we get tied down by accidents of history. A lot of your proposals for subsetting JavaScript and your version of HTML5 seem to be attempts to fix these kinds of historical accidents.
Crockford: Yeah, and some of it is quixotic. 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. Like when XML was proposed as a data-interchange format, my first impression of that was, “My god, this is way, way, way too complicated. We don’t need all of this stuff just to move data back and forth.” And so I proposed another way to do it, and it won. JSON is now the preferred way of doing data transfer in Ajax applications and it’s winning in a whole lot of other applications. And it’s just really simple. So that restores my faith in humanity, that maybe we can finally get some of these things right.
But you can’t have everybody going off, making up their own thing. That doesn’t work. That doesn’t do anybody any good. But one person has to make up a thing and everyone else has to figure out how to agree which one of those we’re all going to get behind. JSON was a different kind of accident of history.
Seibel: Overall, do you think that the software industry is a brilliant engine of innovation or a horrible mess?
Crockford: I’m trying to think of a nice way to say, “Horrible mess.” I’d think generally software has gotten better. Not at the same pace that Moore lets the hardware got better. We track way, way slow compared to him, so it takes us 20 years to double our efficiency in software development. But we have seen improvement. Most of our improvement is due to the fact that we don’t have to make it fit anymore. We don’t have to make it fast anymore. So that should have liberated us to just making it good. But we don’t spend enough time doing that, I think.
Seibel: So if we are, however nicely you put it, a horrible mess, what could we do to not be such a mess?
Crockford: That’s what I’m trying to figure out. A lot of it I think has to do with the way that we create standards. The reason why things are working as well as they are now is because the Net works; all the benefits that came, came from being able to tie everything together and have that happen pretty reliably.
But you don’t have to scratch it very deep to find places where we got that wrong, where we could’ve got it better. The dilemma is, how do we fix this stuff in place? Anytime we change a software standard, it’s an act of violence. It is disruptive. It will cause stuff to fail. It will cause cost and harm to people. So we need to be really careful when we revise the standards because there is that cost. We have to make sure that we’re adding so much value to offset that cost. From what I see of the way that standards are being manipulated right now, that’s not occurring. Standard changes are being motivated by “we want to do it” or “because it’d be neat” or some other motivation which is not necessarily closely related to creating a lot of value for the world. So I’m struggling with that. How do we get better at that?
Seibel: You seem to lean toward specifying less. That, obviously, is a way to avoid over specifying things and standardizing things that you’re going to regret later. But if less is specified in standards, then people have to make more stuff up and you’re going to have a big pile of de facto standards as people try to settle on OK ways of getting stuff done. Is making standards simpler really going to fix the problem, if the complexity just pops up elsewhere?
Crockford: What we really need to be doing is getting better at predicting what we’re really going to need in the future. Maybe we have to wait for time travel before we finally start getting this stuff right. In the meantime, I look on that experimentation and proliferation of possible approaches as a positive thing in that maybe the right approach to take to standardization is to figure out which of those are the best thought out, which are the most maintainable, which are the most growable, and pick that. Rather than a standards committee trying to guess the best way to do it, we pick from examples in the marketplace what is actually demonstrably the best way to do it.
Seibel: But you feel like overall we’re making some progress?
Crockford: Progress isn’t always forward. Sometimes we’re leaping forward and sometimes we’re leaping backwards. When we leaped to the PC, we lost a whole lot of stuff. In the timesharing era, we had social systems online. A timesharing system was a marketplace. It was a community and everybody who was a part of that system could exchange email, they could exchange files, they could chat, they could play games. They were doing all this stuff and all that got lost when we went to PCs. It took another 20 years or so to get that back.
We also took a huge step backwards in terms of security. Timesharing systems were starting to understand how to defend the system and the users of the system from each other. When we went to PCs, you owned your machine and everything running in that machine had the same privileges, the same rights to do whatever it had to do, and it turned out that not all the software running in your machine is acting in your interest. We’re still struggling with that. We’ve seen lots of improvements going into the PC operating systems, but we’re still not at the point where some of the more forward-looking timesharing systems were way, way back.
Seibel: Which ones are you thinking of?
Crockford: MULTICS was doing some really interesting stuff in cooperative processes, and having multiple address spaces which were able to communicate with each other but couldn’t get into each other’s stuff. That’s the basic baseline you need in order to start doing cooperative computing. And we’re now trying to figure out how to get that into the browser. It’s a long time between MULTICS and here. We’re starting now to catch up to insights that were being acted on way back then.
Seibel: I’ve noticed a similar thing with languages—PCs were programmed in assembly because even C was too high-level and only now are we getting back to languages with some of the power of languages like Smalltalk and Lisp that existed when PCs came out. I wonder if programmers are as aware of the relatively short history of our field as they could be, or do we keep reinventing the wheel?
Crockford: I think we’re tragically unaware of our history, and I’m often really disappointed to see that people who are now practicing this craft having no intellectual curiosity about where this stuff came from and just assume that some committee got it right and presented them with a set of tools or languages, and all they have to do is use it properly.
There are amazing stories about where this stuff came from, and what influenced what, and who did what, and what is now considered a mistake, and what should be considered a mistake, but hasn’t yet. I think of myself sometimes as an archaeologist of software technology and over the years I’ve accumulated this collection of underappreciated technology, things that I think were really, really good, which are significantly in advance of the state of the art of what we’re doing now. I keep hoping that we will somehow rediscover this stuff and learn to appreciate it and benefit from having done it, but it’s a really slow process. I see folks are really entrenched in the way that things are working right now and it’s really difficult to move.
Seibel: What are some of those technologies?
Crockford: Lisp and Smalltalk, you’ve just mentioned. That’s brilliant stuff, and we’re now finally seeing those ideas being factored into modern languages, so we’re doing a lot of work now in JavaScript and trying to modernize that. It turns out JavaScript already anticipated a bunch of that stuff; it’s got functions which are lexically scoped and first-class, which was brilliant. Now we’re trying to figure out how to get more of the goodness of Smalltalk and Scheme into this language without breaking it. You could argue that we’d be better off if we just threw out everything we’re working on now and go back to Smalltalk and Scheme, and we probably would be better off than we are right now, but that doesn’t appear to be an option.
As we’re getting more and more into mash-ups, we want to have code from all over the place—stuff that we’ll never, ever test with—actually run out in the field. Which is a new kind of programming. We’ve never done that before. I think that’s the future of programming and we’re getting to it in JavaScript first and it’s working here because the language, in spite of all the stuff it got wrong, got this other stuff right.
Looking at where we’ve come on the timeline of programming, we started with machine codes and then we took a leap to symbolic assembly language and then we took a leap to high-level languages and then we took a leap to structured programming and then we took a leap to object-oriented programming. And each of these leaps takes about a human generation.
We’re overdue on the next one. We’ve been at object for a while. You could argue it was Smalltalk-80. You could go back a little bit earlier, but we’ve been sitting on these ideas for a long time.
I think the next leap, we don’t know what the name of it is yet, but I think it’s something related to mash-ups where we can casually take bits of program and put them together and immediately make new programs. We’ve been talking for decades about a model of programming in which we snapped programs together like LEGO and make stuff. That hasn’t happened yet. But I think it is starting to happen now and the place it’s happening is in JavaScript, which is the least likely place.
Seibel: When you’re hiring programmers, how do you recognize the good ones?
Crockford: The approach I’ve taken now is to do a code reading. I invite the candidate to bring in a piece of code he’s really proud of and walk us through it.
Seibel: And what are you looking for?
Crockford: I’m looking for quality of presentation. I want to see what he thinks is something he’s proud of. I want to see evidence that in fact he is the author of the thing that he’s defending. I find that is much more effective than asking them to solve puzzles or trivia questions. I see all that kind of stuff as useless. But how effectively they can communicate, that’s a skill that I’m hiring for.
Seibel: Do you have any advice for self-taught programmers?
Crockford: Yeah, read a lot. There are good books out there. Find the good ones and read those. And if you’re doing web development, find the best sites and look at their code. Although I’m a little reluctant to give that advice yet. Most web developers learned to do web development by doing “view source,” and until fairly recently, most of the source that was out there was very bad. So you had a generation of programmers who were raised on really bad examples, thinking bad code was the way to write.
That’s getting better now, but there’s still so much bad stuff out there that I’m reluctant to give that advice yet.
Seibel: What about advice for someone who’s actually getting a C.S. degree who wants to work as a programmer?
Crockford: I would focus on the communication aspect. Learn to write; learn to read.
My advice to everybody is pretty much the same, to read and write. I generally don’t hire for specific skills. Until very recently, you couldn’t hire good JavaScript programmers. They were extremely rare. There are a lot of really good ones out there now, but that’s a fairly recent thing. So until that happened, I would just hire for quality. Are you a good Java programmer, a good C programmer, or whatever? I don’t care. I just want to know that you know how to put an algorithm together, you understand data structures, and you know how to document it. If you can do that, you should be able to figure out JavaScript.
Seibel: Have you ever had problems with that? People who’ve been successful in one language sometimes have a hard time giving up their old ways, even when working in a new language where they don’t really make sense.
Crockford: I have with, say, Windows programmers. Windows has a number of very complicated APIs and you can spend years just understanding how those APIs work. And that’s pretty much all you do, is you know that one API. You can write a window handle but there’s not much else you can do. I tend not to look for that kind of overspecialization unless I have a really specific niche. Generally, I prefer generalists. I want someone who’s capable of learning any of those APIs but isn’t necessarily skilled in any one.
Seibel: You said earlier that you got into computers because you thought they would make the world a better place.
Crockford: That’s my intention.
Seibel: How’s that working out?
Crockford: For the most part, we’ve done pretty good. I think the world is a better place, although it’s not always moving forward. Looking at, say, international politics over the last ten years, the consolidation of big media and the corrupting effects of that have not been compensated for by the open network. That’s a big disappointment.
Hundreds of thousands of people have died as a direct consequence of that. That’s really sad. I would like for the network to be doing a better job so that kind of stuff doesn’t happen again. It’s not clear yet what transformations to the network have to occur in order to accomplish that. And maybe it’ll be fine on its own, but I’m more pessimistic. I think we need to figure out the next leap in order to overcome whatever is not working now.
Seibel: Wouldn’t the gazillion bloggers out there say, “Hey, we’re out here blogging about everything and the mainstream media is taking it in the pants.”
Crockford: Yeah, that’s great. We still got it wrong. We’ve got this great thing where we can all get wired together and we can all get the message out to each other, but it’s not working. It’s just a lot of noise at this point.
Seibel: And do you think that part of that solution of that problem will be technical? Is there something programmers or system designers can do to tweak the architecture that will help? Or is it a social problem?
Crockford: It may be that new social systems have to evolve on top of this new network infrastructure and it’s just immature at this point and that’s why it’s not working. Maybe it just solves itself. I’m hoping that’s the case. But I think there may be more involved. Right now, the network does an extremely poor job of identity, does an extremely poor job of security, and those are a necessary component, I think, of building robust social systems. So that aspect of the Web is still deficient and maybe that’s why it’s so noisy still.