Выбрать главу

When you write Haskell programs you’re forced to decide your proof system in advance of knowing what it is you’re doing. Dynamic languages became popular because people can actually rapidly prototype and keep this latent type system in their head. Then maybe later on, if they have a language that can support it, or if they’re recoding in a static language, they can write down the types. That was one of the reasons why in JavaScript we were interested in optional typing and we still are, though it’s controversial in the committee. There’s still a strong chance we’ll get some kind of hybrid type system into a future version of JavaScript.

So we would like to annotate our C++ with annotations that conservative static analysis could look at. And it would be conservative so it wouldn’t fall into the halting-problem black hole and take forever trying to go exponential. It would help us to prove things about garbage-collector safety or partitioning of functions into which control can flow from a script, functions from which control can flow back out to the script, and things to do with when you have to rematerialize your interpreter stack in order to make security judgments. It would give us some safety properties we can prove. A lot of them are higher-level properties. They aren’t just memory safety. So we’re going to have to keep fighting that battle.

Seibeclass="underline" So that’s a very high-level view of programming. How close to the metal do you think programmers today need to be able to go? If someone is going to be writing most of their applications in JavaScript, is it still important that they grok assembly?

Eich: I know a lot of JavaScript programmers who are clever programmers, and the best ones have a good grasp of the economics. They benchmark and they test as they go and they write tight JavaScript. They don’t have to know about how it maps to machine instructions.

A lot of them are interested in that when they hear about these JITing, tracing VMs that we’re building. And we’re getting more and more people who are pushing pixels. If you give people enough programming-language performance and enough pixel-pushing power I think JavaScript programmers will start using JavaScript at a lower level. And machine economics or the virtual-machine economics—what really matters? Maybe it’s the virtual-machine economics.

Abstraction is powerful. What I’m really allergic to, and what I had a bad reaction to in the ’90s, was all the CORBA, COM, DCOM, object-oriented nonsense. Every startup of the day had some crazy thing that would take 200,000 method calls to start up and print “hello, world.” That’s a travesty; you don’t want to be a programmer associated with that sort of thing. At SGI, the kernel, of course, was where the real programmers with chest hair went, and there you couldn’t screw around. Kernel malloc was a new thing; we still used fixed-sized tables, and we panicked when we filled them up.

Staying close to the metal was my way of keeping honest and avoiding the bullshit, but now, you know, with time and better, faster hardware and an evolutionary winnowing process of good abstractions versus bad, I think people can operate above that level and not know assembly and still be good programmers and write tight code.

Seibeclass="underline" Do you think, conversely, that the people who, back in the day, could write intricate, puzzle-box assembly code, would be just as great programmers in today’s world doing high-level programming? Or does that kind of programming require different skills?

Eich: I would say for certain aspects of programming there is a correspondence between the two. There’s a difference between raw pointers and this happy, fun JavaScript world. That kind of still separates the chest hair—gender-independent—programmers from those who don’t quite have it.

Keeping it all in your head is important. Obviously people have differentsized heads. Somebody with a big head could keep track of higher-level invariants in a memory-safe architecture and not have to worry about pointers. But there’s something still that bothers me if over time we lose the ability to write to the metal. Somebody’s doing it; the compiler is generating the code. The compiler writers have to be doing a better job over time.

Seibeclass="underline" So there will always be a place for that kind of programming. But are there people who can be successful programmers now who just couldn’t when all programming was low-level hacking? Or is there one fixed population of people who have the right kind of brain for programming and now they’re split with some people doing low-level stuff and some people doing high-level stuff?

Eich: I haven’t hacked kernel code in a long time, so I would have to go for there’s some ability to migrate. There’s more code to write. And sound abstractions give you leverage over problems you couldn’t address before.

Seibeclass="underline" Let’s go back to those ten days when you implemented the original JavaScript. I know that at some point someone had turned you on to Abelson and Sussman and your original idea was to put Scheme in the browser.

Eich: The immediate concern at Netscape was it must look like Java. People have done Algol-like syntaxes for Lisp but I didn’t have time to take a Scheme core so I ended up doing it all directly and that meant I could make the same mistakes that others made.

I didn’t have total dynamic scope, like Stallman insisted was somehow important for Emacs and infested Elisp with. JavaScript has mostly lexical scope with some oddness to it—there are a few loopholes that are pretty much dynamic: the global object, the with statement, eval. But it’s not like dollar variables in Perl before my or upvar, uplevel in Tcl. The ’90s was full of that—it was trendy.

But I didn’t stick to Scheme and it was because of the rushing. I had too little time to actually think through some of the consequences of things I was doing. I was economizing on the number of objects that I was going to have to implement in the browser. So I made the global object be the window object, which is a source of unknown new name bindings and makes it impossible to make static judgments about free variables. So that was regrettable. Doug Crockford and other object-capabilities devotees are upset about the unwanted source of authority you get through the global object. That’s a different way of saying the same thing. JavaScript has memory-safe references so we’re close to where we want to be but there are these big blunders, these loopholes.

Making those variables in the top level actually become mutable properties of an object that you can alias and mess around with behind the back of somebody—that’s no good. It should’ve been lexical bindings. Because if you go down from there into the functions and nested functions, then it is much more Scheme-like. You don’t quite have the rich binding forms, the fluid lets or whatever; you have more like set-bang. But the initial binding you create with a local variable is a lexical variable.

Seibeclass="underline" So basically now people make a top-level function to get a namespace.

Eich: Yeah. You see people have a function and they call it right away. It gives them a safe environment to bind in, private variables. Doug’s a big champion of this. It was not totally unknown to the Schemers and Lispers but a lot of JavaScript people had to learn it and Doug and others have done a valuable service by teaching them. It’s not like you’re getting everybody to be high-quality Scheme programmers, unfortunately, but to some extent they’ve succeeded, so people now do understand more functional idioms at some patterny level, not necessarily at a deep level.