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

Steele: On the other hand, now Haskell has discovered monads and they have dragged in the I/O monad and now the transactional-memory monad. There’s a theory that it’s functional and maybe that does give you a leg up. On the other hand it’s feeling more and more imperative. And I can’t resist thinking of the White Knight in Through the Looking Glass—“I was thinking of a plan to dye one’s whiskers green, and always use so large a fan that they could not be seen.” And in some ways, monads strike me as that fan, where you’re dragging in the I/O and trying to hide it again—are the side effects really there, or are they really not?

Although I will say that about once a month I get the feeling that I wish that in designing Fortress we had started with Haskell and tried to move it toward Fortran and Java, rather than starting with Fortran and Java and trying to move it toward Haskell. We are finding ourselves taking more and more of a functional approach as we design the Fortress libraries as we encounter the difficulties of trying to make efficient parallel data structures.

Seibel: You obviously write a lot in English and care about that craft as well. Do you find writing prose and writing code to be similar mental exercises?

Steele: Well, they feel different in that I’m very aware that the primary reader for English prose has a very different kind of processor than a computer. So I can’t use recursion in quite the same way, for example. For sophisticated readers I can use it a little bit. But there’s a constant awareness of how a reader is going to process the text and understand it.

Something I worry about a lot when I write, that I’m less worried about with a computer, is about the ways in which English is ambiguous. I’m constantly worrying about ways in which the reader might misinterpret what I’ve written. So I’ve actually spent a lot of time consciously crafting the mechanics of my prose style to use constructions that are less likely to be misinterpreted.

My favorite Saturday Night Live sketch, even more than the bees or the wild and crazy guys, was a sketch where Ed Asner was on and he played the manager of a nuclear power plant going on vacation for two weeks. He walked out the door, saying, “Goodbye, everybody, I’m going. Remember, you can’t give too much coolant to the nuclear reactor.” And they spend the next three minutes arguing over what he meant.

Seibel: So when you’re writing English, you’re obviously writing for a human reader and you seem to contrast that to writing software, which is for a computer. But lots of people—such as Knuth—make a big point that when you’re writing code you’re writing as much for human readers as for the computer.

Steele: Oh, that’s true.

Seibel: So do the lessons of writing English for a human reader help you with that aspect of code?

Steele: Well, sure. When I’m writing code, one of the foremost things in my mind is, will this get the computer to do what I want? And so it’s a matter of, “Will it be understood even one way?” Rather than not at all. Then there’s the question of often there’s more than one way to write something correctly. And at that point I begin worrying about the human reader. And I also worry about efficiency.

There’s a trade-off there, typically. If efficiency is important, I’ll often resort to a trick. And then I realize that will mislead a human. And you have to comment it or do something to flag that, to make it more readable. But yes, very often in things like choices of variable names and the way code is laid out and so forth, the emphasis is more on the human reader, and you think about how you can use details of the code formatting that don’t matter to the computer to provide the necessary signals to the human reader.

Seibel: As our languages get better, or at least more programmer-friendly, compared to the days of assembly language on punch cards, it seems like it’s easier to write correct programs—you get a lot of help from compilers that flag errors for you and so forth. Is it possible to allow the focus on readability to come first, if only slightly ahead, of correctness? After all, as the Haskell folks are fond of saying, “If your Haskell program type checks, it can’t go wrong.”

Steele: I think that’s a terrible pitfall. There are so many ways for a compilable program to have errors in it that you really do need to worry about correctness all the time. And if it’s not correct you’ll mislead not only the computer but your human readers, too.

Programming is a highly unnatural activity, I’m convinced, and it must be carefully learned. People are used to their listeners filling in the gaps. I suppose we lean on compilers to do that in a little way—you say, “I need a variable named ‘foo’,” you don’t worry about exactly what register and so forth. But I think that most people are not used to being very precise and rigorous in their communications. But when we are describing processes to be carried out, little details do matter because a change in a small detail can affect the gross outcome of the process.

I think people are used to using recursion in a limited way—I think Noam Chomsky demonstrated that. But in practice people rarely go even three deep—and when they do it’s usually in a tail-recursive way. The discipline of understanding recursion is actually a very difficult learned art. And yet that is actually one of our most powerful programming tools, once you’ve learned the discipline and wrapped your head around it. So I really think you can’t afford to take your eye off the correctness ball.

Seibel: Yet lots of people have tried to come up with languages or programming systems that will allow “nonprogrammers” to program. I take it you think that might be a doomed enterprise—the problem about programming is not that we haven’t found the right syntax for it but that people have to learn this unnatural act.

Steele: Yeah. And I think that the other problem is that people like to focus on the main thing they have in mind and not worry about the edge cases or the screw cases or things that are unlikely to happen. And yet it is precisely in those cases where people are most likely to disagree what the right thing to do is.

Sometimes I’ll quiz a student, “What should happen in this case?” “Well, obviously it should do this.” And immediately someone else will jump in and say, “No, no, it should do that.” And those are exactly the things that you need to nail down in a programming specification of some process.

I think it’s not an accident that we often use the imagery of magic to describe programming. We speak of computing wizards and we think of things happening by magic or automagically. And I think that’s because being able to get a machine to do what you want is the closest thing we’ve got in technology to adolescent wish-fulfillment.

And if you look at the fairy tales, people want to be able to just think in their minds what they want, wave their hands, and it happens. And of course the fairy tales are full of cautionary tales where you forgot to cover the edge case and then something bad happens.

Seibel:Fantasia and the perils of recursion, for instance.

Steele:Fantasia and recursion, yes. Or, “I wish I was the richest man in the country”—well, that makes everybody else extremely poor and you’re the same as you were before. That kind of thing happens in fairy tales because people forget that there’s more than one way to do something. And if you just think about your main wish and don’t think about the details, that leaves a lot not tied down.

Seibel: So the lesson from fairy tales is that the Gandalfs of the world got there by hard labor, learning the incantations, and there’s no shortcut to that?

Steele: Yeah. I’ll give you another example—suppose I were to tell my smart computer, “OK, I’ve got this address book and I want the addresses to always be in sorted order,” and it responds by throwing away everything but the first entry. Now the address book is sorted. But that’s not what you wanted. It turns out that just specifying something as simple as “a list is in sorted order and I haven’t lost any of the data and nothing has been duplicated” is actually a fairly tricky specification to write.