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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.
Seibeclass="underline" 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.