Programming is fundamentally different to the way we construct things inthe real world. Imagine you’re a car manufacturer. You buy componentsfrom subcontractors. You buy a battery from Lucas and you buy a generatorfrom somewhere. And you bolt things together—you construct things byplacing things next to each other. You build a house by putting the bricks ontop of each other and putting the door there. That’s how we make chips.You get a printed circuit board that basically just provides this connection.But you can think of making electronic things as you buy all these chips andyou connect the legs of some to others with wires. And that’s how youmake hardware. But we don’t make software like that. We should makesoftware like that and we don’t.

The reason we don’t, has to do with concurrency. You see, the chips, whenyou put them next to each other, they all execute in parallel. And they sendmessages. They are based on this message-passing paradigm ofprogramming, which is what I believe in. And that’s not how we writesoftware together. So I think one direction Erlang might take, or I would likeit to take, is this component direction. I haven’t done it yet, but I’d like tomake some graphic front ends that make components and I’d like to makesoftware by just connecting them together. Dataflow programming is verydeclarative. There’s no notion of sequential state. There’s no programcounter flipping through this thing. It just is. It’s a declarative model and it’svery easy to understand. And I miss that in most programming languages.

That’s not to say that what’s inside an individual black box isn’t verycomplicated. Take grep, for example. Seen from the outside—imagine alittle square. The input is a stream of data, a file. You say cat foo span grepand grep has got some arguments, it’s got a regular expression it’s got tomatch. OK. And out of grep come all the lines that match that regularexpression. Now, at a perceptual level, understanding what grep does isextremely simple. It has an input which is a file. It has an input which is aregular expression. It has an output which is a set of lines or a stream oflines that match the regular expression. But that is not to say that thealgorithm inside the black box is simple—it could be exceedinglycomplicated.

What’s going on inside the black boxes can be exceedingly complicated. Butgluing things together from these complicated components does not itselfhave to be complicated. The use of grep is not complicated in the slightest.And what I don’t see in system architectures is this clear distinctionbetween the gluing things together and the complexity of the things insidethe boxes.

When we connect things together through programming language APIswe’re not getting this black box abstraction. We’re putting them in thesame memory space. If grep is a module that exposes routines in its API andyou give it a char* pointer to this and you’ve got to malloc that and did youdeep copy this string—can I create a parallel process that’s doing this? Thenit becomes appallingly complicated to understand. I don’t understand whypeople connect things together in such complicated ways. They shouldconnect things together in simple ways.

Seibel: Comparing how you think about programming now with how youthought when you were starting out, what’s the biggest change in yourthinking?

Armstrong: The big changes in how I think about programming havenothing to do with the hardware. Obviously it’s a lot faster and lot morepowerful but your brain is a million times more powerful than the bestsoftware tools. I can write programs and then suddenly, days later, say,“There’s a mistake in that program—if this happens and that happens andthat happens and this happens, then it will crash.” And then I go and look inthe code—yup, I was right. There has never been a symptom. Now you tellme a development system that can do that kind of stuff. So the changes thathave happened as a programmer, they’re mental changes within me.

There are two changes and I think they’re to do with the number of yearsyou program. One is, when I was younger quite often I would write aprogram and work at it until it’s finished. When it was finished I would stopworking on it. It was done, finished. Then I’d get an insight—“Ah! Wrong!Idiot!” I’d rewrite it. Again: “Yeah, it’s wrong”—rewrite it.

I remember thinking to myself, “Wouldn’t it be nice if I could think all of thisstuff instead of writing it?” Wouldn’t it be nice if I could get this insightwithout writing it. I think I can do that now. So I would characterize thatperiod, which took 20 years, as learning how to program. Now I know howto program. I was doing experiments to learn how to program. I think Iknow how to program now and therefore I don’t have to do theexperiments anymore.

Occasionally I have to do very small experiments—write extremely smallprograms just to answer some question. And then I think through things andthey more or less work as I expect when I program them because I’vethought through them. That also means it takes a long time. A program thatyou write, you get the insight, you rewrite—it might take you a year towrite. So I might think about it for a year instead. I’m just not doing all thistyping.

That’s the first thing. The second thing that’s happened is intuition. When Iwas younger, I would do the all-night hacks, programming to four in themorning and you get really tired and it’s macho programming—you hack thecode in hour after hour. And it’s not going well and you persevere and youget it working. And I would program when the intuition wasn’t there.

And what I’ve learned is, programming when you’re tired, you write crap and youthrow it all away the next day. And 20 years ago I would program although I wasgetting a strong feeling that this isn’t right—there’s something wrong withthis code. I have noticed over the years, the really good code I would writewas when I’m in complete flow—just totally unaware of time: not even reallythinking about the program, just sitting there in a relaxed state just typingthis stuff and watching it come out on the screen as I type it in. That code’sgoing to be OK. The stuff where you can’t concentrate and something’s saying,“No, no, no, this is wrong, wrong, wrong”—I was ignoring that years ago. AndI’d throw it all away. Now I can’t program anymore if it says, “No.” I justknow from experience, stop—don’t write code. Stop with the problem. Dosomething else.

Because I was good at math and that sort of stuff at school, I thought, “Oh,I’m a logical person.” But I took these psychology tests and got way highscores on intuition. And quite low scores on logical thinking. Not low—Ican do math and stuff; I’m quite good at them. But because I was good atmath I thought science was about logic and math. But I wouldn’t say thatnow. I’d say it’s an awful lot of intuition, just knowing what’s right.

Seibel: So now that you spend more time thinking before you code, whatare you actually doing in that stage?

Armstrong: Oh, I’m writing notes—I’m not just thinking. Doodling onpaper. I’m probably not committing much to code. If you were to monitormy activity it’d be mostly thinking, a bit of doodling. And another thing, veryimportant for problem solving, is asking my colleagues, “How would yousolve this?” It happens so many times that you go to them and you say, “I’vebeen wondering about whether I should do it this way or that way. I’ve gotto choose between A and B,” and you describe A and B to them and thenhalfway through that you go, “Yeah, B. Thank you, thank you very much.”

You need this intelligent white board—if you just did it yourself on a whiteboard there’s no feedback. But a human being, you’re explaining to them onthe white board the alternative solutions and they join in the conversationand suggest the odd thing. And then suddenly you see the answer. To methat doesn’t extend to writing code. But the dialog with your colleagueswho are in the same problem space is very valuable.


Перейти на страницу:
Изменить размер шрифта: