Mind / Matter
things that count
DN Logo



Click here to send an email. DN


-11585
065410
Commentary: Paul Graham on `The Hundred-Year Language'

This note is a commentary on one of Paul Graham's papers that is available at his site. It presents another `parallelogue' where I comment on the piece pretty much paragraph by paragraph.

DN Title Graham David Ness
Keynote This article is derived from a keynote talk given at PyCon 2003.
Introduction It's hard to predict what life will be like in a hundred years. There are only a few things we can say with certainty. We know that everyone will drive flying cars, that zoning laws will be relaxed to allow buildings hundreds of stories tall, that it will be dark most of the time, and that women will all be trained in the martial arts. Today I want to zoom in on one detail of this picture. What kind of programming language will they use to write the software controlling those flying cars? I have a hard time knowing whether this is `tongue-in-cheek' or not. I assume it is. But surely the picture is a lot like the one presented at the 1939 World's Fair, and in the 65 years from that time the world `looks' more like it did then than it does like the futuristic utopia that was supposed to be `just around the corner'. But I suppose ultimately it doesn't matter much. I guess this is just introductory fluff. But it does suggest the danger with assuming that one can make any reasonable guesses about the long run of history.
Getting there is the fun This is worth thinking about not so much because we'll actually get to use these languages as because, if we're lucky, we'll use languages on the path from this point to that. One of the interesting points about many real-world situations is that paying excessive attention to `final goals' often proves to be distractive and destructive to all that good that might be accomplished getting somewhere, even if final goals aren't agreed on. Graham starts out by asserting that this relationship between goals and means is productive. That's an unproven---indeed even unargued---assumption. I disagree with it.
Evolutionary Trees I think that, like species, languages will form evolutionary trees, with dead-ends branching off all over. We can see this happening already. Cobol, for all its sometime popularity, does not seem to have any intellectual descendants. It is an evolutionary dead-end--a Neanderthal language. Lots of evolutionary `innovation' ultimately died out. So this is nothing new with regard to computer languages. Evolution, by its very nature, is a mechanism which involves lots of branches and pruning.
Java and Cobol I predict a similar fate for Java. People sometimes send me mail saying, "How can you say that Java won't turn out to be a successful language? It's already a successful language." And I admit that it is, if you measure success by shelf space taken up by books on it (particularly individual books on it), or by the number of undergrads who believe they have to learn it to get a job. When I say Java won't turn out to be a successful language, I mean something more specific: that Java will turn out to be an evolutionary dead-end, like Cobol. This makes me unsure about what Graham means by `success'. I assume he'd claim Lisp is a great success, even though its installed base is fairly small. What about Algol? I'd rather suspect that more new code is written today in COBOL than in ALGOL, though I'm not sure that it matters much.
Not Dissing Java: This is just a guess. I may be wrong. My point here is not to diss Java, but to raise the issue of evolutionary trees and get people asking, where on the tree is language X? The reason to ask this question isn't just so that our ghosts can say, in a hundred years, I told you so. It's because staying close to the main branches is a useful heuristic for finding languages that will be good to program in now. This is a very interesting argument, but not one that I am willing to believe just by assertion. In chess, staying very close to main branches may be very effective strategy, but in the game of `Go' this is probably not the case. In `Go' well placed outliers are more likely to lead to great victories than are middle-of-the-road strategies. It remains to be seen which of these games might better model the computer software design process.
The Main Branch: At any given time, you're probably happiest on the main branches of an evolutionary tree. Even when there were still plenty of Neanderthals, it must have sucked to be one. The Cro-Magnons would have been constantly coming over and beating you up and stealing your food. Again. This may be true, but I am not convinced by just further repitition of the assertions.
The Hundred-Year Bet: The reason I want to know what languages will be like in a hundred years is so that I know what branch of the tree to bet on now. This, too, relies on what I would regard to be a dubious assertion. If I read Graham's argument correctly, he's suggesting that it is better to `make the leap' today than to engage in some process that might move us into our future more gradually. As of this time, I have no reason to believe this.
Convergence The evolution of languages differs from the evolution of species because branches can converge. The Fortran branch, for example, seems to be merging with the descendants of Algol. In theory this is possible for species too, but it's so unlikely that it has probably never happened. So far I'll accept this point.
Likely Convergence: Convergence is more likely for languages partly because the space of possibilities is smaller, and partly because mutations are not random. Language designers deliberately incorporate ideas from other languages. Asserted, but I don't yet see either the importance of the point or the support for it.
Stay on a Main Branch It's especially useful for language designers to think about where the evolution of programming languages is likely to lead, because they can steer accordingly. In that case, "stay on a main branch" becomes more than a way to choose a good language. It becomes a heuristic for making the right decisions about language design. It occurs to me that the opposite of this view might be described as the `make use of special circumstances' approach. This approach seems to be equally effective---indeed sometimes much more effective, in some circumstances. I see little reason to believe one approach to the exclusion of the other without some much better evidence than is being presented here.
Two Parts Any programming language can be divided into two parts: some set of fundamental operators that play the role of axioms, and the rest of the language, which could in principle be written in terms of these fundamental operators. Okay.
Fundamental Operators I think the fundamental operators are the most important factor in a language's long term survival. The rest you can change. It's like the rule that in buying a house you should consider location first of all. Everything else you can fix later, but you can't fix the location. The analogy seems quite weak to me. While I might agree with the view that the `location' is the hardest thing to change about a house, the application of this analogy to `operators' seems stretched at best. I't does seem to me that---at least to a limited extent---I can fix the operators if I need to.
Axioms: I think it's important not just that the axioms be well chosen, but that there be few of them. Mathematicians have always felt this way about axioms-- the fewer, the better-- and I think they're onto something. Okay.
Look at the Core: At the very least, it has to be a useful exercise to look closely at the core of a language to see if there are any axioms that could be weeded out. I've found in my long career as a slob that cruft breeds cruft, and I've seen this happen in software as well as under beds and in the corners of rooms. I sort of doubt if cruft `breeds' cruft. I'd be more tempted to say that the habit a neglecting cruft is easy to develop. But that presents a rather different model of the problem. And it's one that I think is much more appropriate than the one presented. Human languages are testimony to the usefulness, in the broader sphere, of `cruft'. And cruft-less languages, perhaps Esperanto being a passible example, rarely prove to be of much long-run effect.
Clean Core: I have a hunch that the main branches of the evolutionary tree pass through the languages that have the smallest, cleanest cores. The more of a language you can write in itself, the better. Again, views that are core `religion' to one cult of programmers. But like most religions, one's truth is another's dubious proposition. I happen to disagree with this one, particularly when advanced without any further evidence.
In a Hundred Years Of course, I'm making a big assumption in even asking what programming languages will be like in a hundred years. Will we even be writing programs in a hundred years? Won't we just tell computers what we want them to do? Maybe. I don't think I'd put heavy money on either side of this particular proposition. There's too much to worry about between now and then to have any real security in guessing.
Programming Then: There hasn't been a lot of progress in that department so far. My guess is that a hundred years from now people will still tell computers what to do using programs we would recognize as such. There may be tasks that we solve now by writing programs and which in a hundred years you won't have to write programs to solve, but I think there will still be a good deal of programming of the type that we do today. Isn't this in some form of conflict with the notion that we know a lot about what the future will look like as was discussed near the beginning of this paper? I find it a rather Herculean stretch. It seems to me just as likely that there won't be much `programming' of the type we do today that is of interest. Indeed, haven't we already seen this with `compiler writing'? Thirty years ago we taught a lot of people how to write compilers. Now it's regarded as a pretty esoteric effort, engaged in by relatively few people.
The Past: It may seem presumptuous to think anyone can predict what any technology will look like in a hundred years. But remember that we already have almost fifty years of history behind us. Looking forward a hundred years is a graspable idea when we consider how slowly languages have evolved in the past fifty. I think this is what I have been saying, and since I thought I was disagreeing with Graham, I am rather startled to find that here he agrees. We'll have to see how this develops.
Notation: Languages evolve slowly because they're not really technologies. Languages are notation. A program is a formal description of the problem you want a computer to solve for you. So the rate of evolution in programming languages is more like the rate of evolution in mathematical notation than, say, transportation or communications. Mathematical notation does evolve, but not with the giant leaps you see in technology. Was this always true of mathematics? Given the state of knowledge of the time there seems to me to have been some rather substantial leaps around the time of Newton and Leibnitz. But then I don't really know enough of the history of mathematics to really be able to assert that with any definiteness.

A further notion deserves investigation in this context. Technologies evolve because of demand pull. There's profit to be made out of doing something a new and better way. And that profit may disappear quite quickly unless we take immediate advantage of it. Notations don't have this characteristic. They evolve because of supply push and it probably doesn't matter much if we rush to take advantage of an `innovation' or not. Time will, and can, tell. So there's no need to hurry.

Moore's Law Whatever computers are made of in a hundred years, it seems safe to predict they will be much faster than they are now. If Moore's Law continues to put out, they will be 74 quintillion (73,786,976,294,838,206,464) times faster. That's kind of hard to imagine. And indeed, the most likely prediction in the speed department may be that Moore's Law will stop working. Anything that is supposed to double every eighteen months seems likely to run up against some kind of fundamental limit eventually. But I have no trouble believing that computers will be very much faster. Even if they only end up being a paltry million times faster, that should change the ground rules for programming languages substantially. Among other things, there will be more room for what would now be considered slow languages, meaning languages that don't yield very efficient code. Again, this may mix the issues of demand pull with those of supply push. There already seems to be gathering evidence that the rate of innovation in chip manufacture is slowing down, and as the profitability departs from the business, one might well expect this decline to accellerate. While I am willing to join Graham in agreeing that things will continue to speed up, I am not particularly optimistic that the effective speed increases will be anywhere as substantial as they have been. Competition (lack of it) may well begin to take care of that fact.

It may also be worth noting that I have heard the `efficiency soon won't matter' argument every year for the past fifty years, and---strangely perhaps---speed seems to still matter just about as much as it did in the 1950s. This is either testimony to the lack of perceptiveness of some of the people in this industry, or it is testimony to the fact that they are slow learners.

Some Speed And yet some applications will still demand speed. Some of the problems we want to solve with computers are created by computers; for example, the rate at which you have to process video images depends on the rate at which another computer can generate them. And there is another class of problems which inherently have an unlimited capacity to soak up cycles: image rendering, cryptography, simulations. I guess I find this point falls into the true, but unimportant category. For example, it seems to me that little of what was important in the development of movies was strongly influenced by the improvements in the `speed' of the technology as we move from a few frames per second up to speeds sufficient to cause the eye to see motion as seamless. Speed increases were simply soaked up into visual improvements that were nice, but not very important conceptually.
Wide Range of Efficiency If some applications can be increasingly inefficient while others continue to demand all the speed the hardware can deliver, faster computers will mean that languages have to cover an ever wider range of efficiencies. We've seen this happening already. Current implementations of some popular new languages are shockingly wasteful by the standards of previous decades. Again we have the issue of what `waste' is in a particular context. And I don't see any particular reason that one should assume that any single language has to `cover an ever wider range of efficiencies'. In my practice I find different languages usedful and effective for different classes of tasks. Some of them are highly `efficient' in some narrow technical context, while others are not. I fail to find a problem here.
General Trend This isn't just something that happens with programming languages. It's a general historical trend. As technologies improve, each generation can do things that the previous generation would have considered wasteful. People thirty years ago would be astonished at how casually we make long distance phone calls. People a hundred years ago would be even more astonished that a package would one day travel from Boston to New York via Memphis. Most of this seems to me to be a misreading of history. There is little `wasteful' in a long distance phone call, for example. More is `wasted' in a local phone call which may well require actual wire, holes in house walls, etc. A call `connected' via satellite uses no more equipment over a long distance than it does to reach a house down the block, so whatever is going on, `wastefulness' would be an inappropriate way to describe it.
Extra Cycles I can already tell you what's going to happen to all those extra cycles that faster hardware is going to give us in the next hundred years. They're nearly all going to be wasted. `Waste' is in the eye of the beholder. One man's waste is another man's fertile manure.
Power was Scarce: I learned to program when computer power was scarce. I can remember taking all the spaces out of my Basic programs so they would fit into the memory of a 4K TRS-80. The thought of all this stupendously inefficient software burning up cycles doing the same thing over and over seems kind of gross to me. But I think my intuitions here are wrong. I'm like someone who grew up poor, and can't bear to spend money even for something important, like going to the doctor. It's difficult to keep learning to effectively spend resources when their factor prices change dramatically with time.
Waste, or Waste Not Some kinds of waste really are disgusting. SUVs, for example, would arguably be gross even if they ran on a fuel which would never run out and generated no pollution. SUVs are gross because they're the solution to a gross problem. (How to make minivans look more masculine.) But not all waste is bad. Now that we have the infrastructure to support it, counting the minutes of your long-distance calls starts to seem niggling. If you have the resources, it's more elegant to think of all phone calls as one kind of thing, no matter where the other person is. But this misses at least part of the point. Depending on the purpose we may well `not care' where the other person is most of the time we make a phone call. If we want to make a dinner appointment, then the location of the reciever may matter, but for much of our phone traffic location doesn't matter at all. The relationship between the phone call and location is an artifact of a delivery system that is now passe.
Good vs. Bad Waste There's good waste, and bad waste. I'm interested in good waste---the kind where, by spending more, we can get simpler designs. How will we take advantage of the opportunities to waste cycles that we'll get from new, faster hardware? If `by spending more, we get simpler designs' then I don't think I'd be very tempted to call it `waste'. Is a car battery a `waste'? We could always return to a hand crank to start our cars, so in one sense they are unnecessary (for starting purposes anyway), but I am not tempted to treat them as a waste.
Overcoming the Need for Speed: The desire for speed is so deeply engrained in us, with our puny computers, that it will take a conscious effort to overcome it. In language design, we should be consciously seeking out situations where we can trade efficiency for even the smallest increase in convenience. I suppose this is true, but again it doesn't seem to be a very important case to discuss to me. In all aspects of life we regularly trade some measure of narrow `efficiency' for increases in convenience. So, while it's a point, it's not one that goes far.
Data Structure and Speed: Most data structures exist because of speed. For example, many languages today have both strings and lists. Semantically, strings are more or less a subset of lists in which the elements are characters. So why do you need a separate data type? You don't, really. Strings only exist for efficiency. But it's lame to clutter up the semantics of the language with hacks to make programs run faster. Having strings in a language seems to be a case of premature optimization. Or why do you need integers? J and K, for example, pretty much handle strings as lists. K goes one step further and pretty much avoids integers, except for `indexing' purposes. In the K4 specification the extra step of eliminating integers alltogether was, if I recall correctly, at least considered.
More on Axioms: If we think of the core of a language as a set of axioms, surely it's gross to have additional axioms that add no expressive power, simply for the sake of efficiency. Efficiency is important, but I don't think that's the right way to get it. Graham gets something out of the `axiom' model. I fail to get it. But to say that `it's gross to have additional axioms that add no expressive power' seems wrong to me. At least if I judge properly from natural language, `additional axioms' are often at the core of particular effectivness with regard to some set of problems.
Meaning vs. Details The right way to solve that problem, I think, is to separate the meaning of a program from the implementation details. Instead of having both lists and strings, have just lists, with some way to give the compiler optimization advice that will allow it to lay out strings as contiguous bytes if necessary. But, as they say, the devil is in the details. Just what is meaning and what constitutes an implementation detail may be in the eye of the beholder.
Speed Doesn't Matter Since speed doesn't matter in most of a program, you won't ordinarily need to bother with this sort of micromanagement. This will be more and more true as computers get faster. I'm not so sure. Computers have already gotten a lot faster and we still need to spend a lot of time micromanaging things when they are important.
Less About Implementation: Saying less about implementation should also make programs more flexible. Specifications change while a program is being written, and this is not only inevitable, but desirable. And saying `less about implementation' is probably a valid goal, but only in circumstances where we don't want to `say more about implementation'. In other words, I find this all pretty much begging the issue. Being able to not overspecify is important. When we don't care, we shouldn't have to care. But in many circumstances we may well really care, and then being able to say so becomes critical.
An Essay: The word "essay" comes from the French verb "essayer", which means "to try". An essay, in the original sense, is something you write to try to figure something out. This happens in software too. I think some of the best programs were essays, in the sense that the authors didn't know when they started exactly what they were trying to write. There seems to be a bit of a logical break here, but I'll let that pass. Graham is (correctly in my opinion) observing that often we start to write without completely understanding what we are trying to do, and it is only as we begin to expose our thoughts that we really begin to discover what is going on. However, this raises a complex and troubling point for his general reasoning. It is often the case in my experience, at least, that the kind of language which is best for the discovery of understanding is not the hundred-year language that he has been discussing.
Lisp Hackers: Lisp hackers already know about the value of being flexible with data structures. We tend to write the first version of a program so that it does everything with lists. These initial versions can be so shockingly inefficient that it takes a conscious effort not to think about what they're doing, just as, for me at least, eating a steak requires a conscious effort not to think where it came from. I guess I'm glad to say that I don't need a conscious effort not to think about my food as I'm eating it. I guess it is perhaps the Francophile in me. But I would find it positively uncomfortable to have every gustatorial experience accompanied by some discipline to keep me from thinking about it.

A similar point obtains with programming. While I generally do not focus much on efficiency during the first pass at a problem, I don't find it necessary to consciously avoid this focus either. Some consideration of efficiency often leads me to creative and effective problem formulation. Of course, over concern (by tautologous definition?) with efficiency is a hinderance, but this rarely presents serious problems in my experience.

Inefficient Version One What programmers in a hundred years will be looking for, most of all, is a language where you can throw together an unbelievably inefficient version 1 of a program with the least possible effort. At least, that's how we'd describe it in present-day terms. What they'll say is that they want a language that's easy to program in. I guess I find the emphasis on inefficiency just as counter effective as an undue emphasis on efficiency. And I'm not convinced that people a hundred years from now will `want a language that's easy to program in'. I'd suspect that they'd ask for something that would make solving their problems `easy'. That's quite a different thing.
Wasting Programmer Time Inefficient software isn't gross. What's gross is a language that makes programmers do needless work. Wasting programmer time is the true inefficiency, not wasting machine time. This will become ever more clear as computers get faster. An emphasis on `wasting programmer time' may be an artifact of an age when programmer time was in very short supply. Certainly for most of the first 50 years of the computer business this has been the case. However, we are now passing some important thresholds, and it is not so clear that this is the case any longer. Programmers have gone from being sought after `bonus babies of Silicon Valley' to out of work SoMa job seekers, finding employment in moving foreclosed furniture from overly fancy lofts.
Getting Rid of Strings: I think getting rid of strings is already something we could bear to think about. We did it in Arc, and it seems to be a win; some operations that would be awkward to describe as regular expressions can be described easily as recursive functions. An example or two would be nice. I don't disagree with the general point, as several languages have `gotten rid of strings', but I'm not sure I see it as much of a general objective. I still find languages that have some native string capability tend to be the best for basic string processing problems.
Flatter Data Structures: How far will this flattening of data structures go? I can think of possibilities that shock even me, with my conscientiously broadened mind. Will we get rid of arrays, for example? After all, they're just a subset of hash tables where the keys are vectors of integers. Will we replace hash tables themselves with lists? Dictionaries may well replace arrays. But, again, probably not for all situations. I'd guess we are heading for a multi-language world where different languages are used for different classes of problems.
McCarthy and Numbers: There are more shocking prospects even than that. The Lisp that McCarthy described in 1960, for example, didn't have numbers. Logically, you don't need to have a separate notion of numbers, because you can represent them as lists: the integer n could be represented as a list of n elements. You can do math this way. It's just unbearably inefficient. And Whitney has pretty much replaced integers by reals. There are some enormous gains in doing so, and while it is occasionally a little bit uncomfortable, once you are used to it, it impinges only a little on style.
Not an Implementation: No one actually proposed implementing numbers as lists in practice. In fact, McCarthy's 1960 paper was not, at the time, intended to be implemented at all. It was a theoretical exercise, an attempt to create a more elegant alternative to the Turing Machine. When someone did, unexpectedly, take this paper and translate it into a working Lisp interpreter, numbers certainly weren't represented as lists; they were represented in binary, as in every other language. Okay.
No Numbers Could a programming language go so far as to get rid of numbers as a fundamental data type? I ask this not so much as a serious question as as a way to play chicken with the future. It's like the hypothetical case of an irresistible force meeting an immovable object---here, an unimaginably inefficient implementation meeting unimaginably great resources. I don't see why not. The future is pretty long. If there's something we can do to decrease the number of axioms in the core language, that would seem to be the side to bet on as t approaches infinity. If the idea still seems unbearable in a hundred years, maybe it won't in a thousand. Sure. But whether this is principally an intellectual exercise or rather something mind-bending still remains to be seen.
In the Core: Just to be clear about this, I'm not proposing that all numerical calculations would actually be carried out using lists. I'm proposing that the core language, prior to any additional notations about implementation, be defined this way. In practice any program that wanted to do any amount of math would probably represent numbers in binary, but this would be an optimization, not part of the core language semantics. I'm afraid the gains of this approach still elude me, but I don't doubt that such an approach would be possible.
Software Layers: Another way to burn up cycles is to have many layers of software between the application and the hardware. This too is a trend we see happening already: many recent languages are compiled into byte code. Bill Woods once told me that, as a rule of thumb, each layer of interpretation costs a factor of 10 in speed. This extra cost buys you flexibility. Okay.
Multi-Level Slowness: The very first version of Arc was an extreme case of this sort of multi-level slowness, with corresponding benefits. It was a classic "metacircular" interpreter written on top of Common Lisp, with a definite family resemblance to the eval function defined in McCarthy's original Lisp paper. The whole thing was only a couple hundred lines of code, so it was very easy to understand and change. The Common Lisp we used, CLisp, itself runs on top of a byte code interpreter. So here we had two levels of interpretation, one of them (the top one) shockingly inefficient, and the language was usable. Barely usable, I admit, but usable. I guess I don't doubt it. Given that we apparently have some disagrement about the meaning of other words, I'd be a bit more comfortable if there was some concrete notion of `usable' advanced, but I don't doubt the point anyway.
Reusability Writing software as multiple layers is a powerful technique even within applications. Bottom-up programming means writing a program as a series of layers, each of which serves as a language for the one above. This approach tends to yield smaller, more flexible programs. It's also the best route to that holy grail, reusability. A language is by definition reusable. The more of your application you can push down into a language for writing that type of application, the more of your software will be reusable. One man's `holy grail' is another's `damnation'. And let's remember that we are talking about programming a hundred-years from now. I could well imagine that by such a time `disposable' might well be more of a `holy grail' than `reusability'. We generally want to re-use stuff only when it has been expensive to develop. Much of the economic advance of the modern age has been to develop disposable resources rather than re-usable resources.

This raises two important points. First, the one we have already made: namely that disposability might be a better goal than reusability. The second, and even more important point is that making any guesses about what will the determining factors at play in the economic situation a hundred years from now is an extremely dangerous business. We simply have no clue. Graham's prognosications are based on some fundamental assumptions which may prove to be grossly wrong.

Object Orientation: Somehow the idea of reusability got attached to object-oriented programming in the 1980s, and no amount of evidence to the contrary seems to be able to shake it free. But although some object-oriented software is reusable, what makes it reusable is its bottom-upness, not its object-orientedness. Consider libraries: they're reusable because they're language, whether they're written in an object-oriented style or not. Well, I don't really get it, but then it doesn't really sound very important either, so I'll let it go.
OO and Large Organizations I don't predict the demise of object-oriented programming, by the way. Though I don't think it has much to offer good programmers, except in certain specialized domains, it is irresistible to large organizations. Object-oriented programming offers a sustainable way to write spaghetti code. It lets you accrete programs as a series of patches. Large organizations always tend to develop software this way, and I expect this to be as true in a hundred years as it is today. Okay. But why?
Parallel Computation: As long as we're talking about the future, we had better talk about parallel computation, because that's where this idea seems to live. That is, no matter when you're talking, parallel computation seems to be something that is going to happen in the future. Maybe it's really just something that is really attractive to talk about, but that doesn't offer so much when you actually think about doing it.
History of Parallel: Will the future ever catch up with it? People have been talking about parallel computation as something imminent for at least 20 years, and it hasn't affected programming practice much so far. Or hasn't it? Already chip designers have to think about it, and so must people trying to write systems software on multi-cpu computers. Didn't it have some influence on `programming practice' back in the days of the CDC 6400 and the original Cray? Maybe it just isn't a very good idea. After all we have witnessed a rather continual swing of the pendulum between simple instruction set computers and complex instruction set computers, with each generation of designer/programmers rediscovering the virtues of the structures which were abandoned by the previous generation of designers.
Ladder of Abstraction: The real question is, how far up the ladder of abstraction will parallelism go? In a hundred years will it affect even application programmers? Or will it be something that compiler writers think about, but which is usually invisible in the source code of applications? This is way too abstract to even guess about.
Wasted Opportunities One thing that does seem likely is that most opportunities for parallelism will be wasted. This is a special case of my more general prediction that most of the extra computer power we're given will go to waste. I expect that, as with the stupendous speed of the underlying hardware, parallelism will be something that is available if you ask for it explicitly, but ordinarily not used. This implies that the kind of parallelism we have in a hundred years will not, except in special applications, be massive parallelism. I expect for ordinary programmers it will be more like being able to fork off processes that all end up running in parallel. It's ok to guess about this, and since Graham is a smart guy it may even be interesting to some. But it doesn't go anywhere for me. So I'll leave it there.
Optimizing: And this will, like asking for specific implementations of data structures, be something that you do fairly late in the life of a program, when you try to optimize it. Version 1s will ordinarily ignore any advantages to be got from parallel computation, just as they will ignore advantages to be got from specific representations of data. Okay, but I miss the point.
Not Pervasive: Except in special kinds of applications, parallelism won't pervade the programs that are written in a hundred years. It would be premature optimization if it did. Okay. And I think this point is well taken and quite understandable.
How Many Languages? How many programming languages will there be in a hundred years? There seem to be a huge number of new programming languages lately. Part of the reason is that faster hardware has allowed programmers to make different tradeoffs between speed and convenience, depending on the application. If this is a real trend, the hardware we'll have in a hundred years should only increase it. Agreed.
Widely Used Languages And yet there may be only a few widely-used languages in a hundred years. Part of the reason I say this is optimism: it seems that, if you did a really good job, you could make a language that was ideal for writing a slow version 1, and yet with the right optimization advice to the compiler, would also yield very fast code when necessary. So, since I'm optimistic, I'm going to predict that despite the huge gap they'll have between acceptable and maximal efficiency, programmers in a hundred years will have languages that can span most of it. How often, in the 60 or so years that we have had so far, is this the pattern of development that has been followed. We still have FORTRANs, of course, but they are not dominantly effective or efficient. Instead we have innovated in completely new dimensions. I'd expect this same kind of dimensional innovation to continue over the next hundred years.
Profilers: As this gap widens, profilers will become increasingly important. Little attention is paid to profiling now. Many people still seem to believe that the way to get fast applications is to write compilers that generate fast code. As the gap between acceptable and maximal performance widens, it will become increasingly clear that the way to get fast applications is to have a good guide from one to the other. Let's see. Efficiency isn't important, but profilers will become increasingly important? Isn't there some conflict there? I thought we weren't so concerned about `fast' applications, but as President Reagan said `There you go again.' We're right back there at efficiency.
Little Languages: When I say there may only be a few languages, I'm not including domain-specific "little languages". I think such embedded languages are a great idea, and I expect them to proliferate. But I expect them to be written as thin enough skins that users can see the general-purpose language underneath. Again, we may have a problem with `few'. How about natural human languages? with 6 billion people in the world is 1,000 languages `many' or `few'? What about Landin's wonderful `Next 700 Programming Languages'?
Who Will Design? Who will design the languages of the future? One of the most exciting trends in the last ten years has been the rise of open-source languages like Perl, Python, and Ruby. Language design is being taken over by hackers. The results so far are messy, but encouraging. There are some stunningly novel ideas in Perl, for example. Many are stunningly bad, but that's always true of ambitious efforts. At its current rate of mutation, God knows what Perl might evolve into in a hundred years. `Taken over by hackers?' It seems to me that for the vast majority of the 60 years of history the design of languages has firmly been in the hands of hackers. Only for a brief while did the hard-core theoreticians really hold sway in language design.

And I would like to hear more about what Graham regards as the novel> ideas in perl, particularly those that he regards as stunningly bad. I have the vague suspicion that they are perhaps just the ideas that I happen to regard as stunningly good but I can't tell unless he exposes his list.

Research It's not true that those who can't do, teach (some of the best hackers I know are professors), but it is true that there are a lot of things that those who teach can't do. Research imposes constraining caste restrictions. In any academic field there are topics that are ok to work on and others that aren't. Unfortunately the distinction between acceptable and forbidden topics is usually based on how intellectual the work sounds when described in research papers, rather than how important it is for getting good results. The extreme case is probably literature; people studying literature rarely say anything that would be of the slightest use to those producing it. Having spent a career as an academic I can confidently say that I am (perhaps blissfully) unaware of any caste restrictions on my research efforts. Of course it is not the case that everyone was always willing to support whatever research I wanted supported. But in virtually every case I was able to find someone to support whatever research I wanted to do, and this is all that mattered. Then again this may have been a result of the fact that I had the good luck to only work for first-class research institutions. Life may well have been more difficult elsewhere.

And it is demeaning to suggest that `people studying literature rarely say anything that would be of the slightest use to those producing it'. The same can be said of art critics, music critics, financial researchers, or those involved in just about any other form of research.

Science Though the situation is better in the sciences, the overlap between the kind of work you're allowed to do and the kind of work that yields good languages is distressingly small. (Olin Shivers has grumbled eloquently about this.) For example, types seem to be an inexhaustible source of research papers, despite the fact that static typing seems to preclude true macros---without which, in my opinion, no language is worth using. I think I agree with this point, but it is---at best---a little confusing. I believe that the point being made is essentially that science doesn't necessarily solve current engineering problems, even if the science is pretty good. If that's the point, then I agree, at least as far as it goes. However, there seems to a lot of historical evidence that much good science developed without any particular concern for its usefulness or practicalability. So, while Graham may really love macros, it may be that macros are only a detour on the way to a better formulation. After all, some programmers like FORTRAN FREQUENCY statements.
Open Source The trend is not merely toward languages being developed as open-source projects rather than "research", but toward languages being designed by the application programmers who need to use them, rather than by compiler writers. This seems a good trend and I expect it to continue. Okay, I guess, but I'm not clear what this implies.
Predicting `In Principle': Unlike physics in a hundred years, which is almost necessarily impossible to predict, I think it may be possible in principle to design a language now that would appeal to users in a hundred years. So far, given the brevity of experience with computation, we can only test this kind of theory in other problem domains. And I'm not sure that history supports the view that Graham advances. The view of 100 years ago proves to be a very shaky guide to today. Of course great literature, art, music, ... all existed then, but quite often the most `valued' works proved to have `no legs'. And there is not much reason to expect, I fear, that the great masters of today will continue to be viewed as great masters 100 years from now. Of course, Graham may be the prescient one who is able to discern today what will prove to be important 100 years from now. But, probably fortunately for him, none of us will be around to evaluate the correctness of his prognostications.
Design by Desire: One way to design a language is to just write down the program you'd like to be able to write, regardless of whether there is a compiler that can translate it or hardware that can run it. When you do this you can assume unlimited resources. It seems like we ought to be able to imagine unlimited resources as well today as in a hundred years. I think I agree with this.
Sources of Influence: What program would one like to write? Whatever is least work. Except not quite: whatever would be least work if your ideas about programming weren't already influenced by the languages you're currently used to. Such influence can be so pervasive that it takes a great effort to overcome it. You'd think it would be obvious to creatures as lazy as us how to express a program with the least effort. In fact, our ideas about what's possible tend to be so limited by whatever language we think in that easier formulations of programs seem very surprising. They're something you have to discover, not something you naturally sink into. What about extra-linguisting influences. Our ideas about `what's possible' are limited by a great deal more than just our experience with other programming languages. They are influenced by our experiences with other media, arts, history, problem solving opportunities and lots of other things. Graham's view, here, is far too dominated by a narrowly procedure-centric orientation.
Size: One helpful trick here is to use the length of the program as an approximation for how much work it is to write. Not the length in characters, of course, but the length in distinct syntactic elements---basically, the size of the parse tree. It may not be quite true that the shortest program is the least work to write, but it's close enough that you're better off aiming for the solid target of brevity than the fuzzy, nearby one of least work. Then the algorithm for language design becomes: look at a program and ask, is there any way to write this that's shorter? I like short programs too. But are our only choices the polar extremes? Must we choose either `least work' or `briefest' or are there a multitude of `good engineering compromises' in between. I guess I often disagree with Graham's taste with respect to design, and this may just be another of those cases. But most of the time in real circumstances I find there are many interesting possibilities that trade off some work for some brevity.
Closeness to Core: In practice, writing programs in an imaginary hundred-year language will work to varying degrees depending on how close you are to the core. Sort routines you can write now. But it would be hard to predict now what kinds of libraries might be needed in a hundred years. Presumably many libraries will be for domains that don't even exist yet. If SETI@home works, for example, we'll need libraries for communicating with aliens. Unless of course they are sufficiently advanced that they already communicate in XML. Another way of saying this, perhaps, is that it is pointless to reach this far into the future. You can't say much about what will be going on.
Or from the Past: At the other extreme, I think you might be able to design the core language today. In fact, some might argue that it was already mostly designed in 1958. Perhaps Graham has something specific in mind (the design of LISP?). If so, it might be useful to make the reference concrete.
Would we Use it?: If the hundred year language were available today, would we want to program in it? One way to answer this question is to look back. If present-day programming languages had been available in 1960, would anyone have wanted to use them? I think the answer is yes. But maybe I better wait for Graham's answer.
Maybe Not: In some ways, the answer is no. Languages today assume infrastructure that didn't exist in 1960. For example, a language in which indentation is significant, like Python, would not work very well on printer terminals. But putting such problems aside---assuming, for example, that programs were all just written on paper---would programmers of the 1960s have liked writing programs in the languages we use now? Putting aside the issue of whether Python's use of indentation is one of those stunningly good or bad ideas, I'm not at all clear about why I would have had trouble with using it on printer terminals. I well remember writing code on `coding sheets' that had well defined character positions so I', not clear about what the problem would have been. And to the general question, my answer is `sure' I do enough writing on paper today, so I'm reasonably certain that I wouldn't have minded.
Less Imaginative: I think so. Some of the less imaginative ones, who had artifacts of early languages built into their ideas of what a program was, might have had trouble. (How can you manipulate data without doing pointer arithmetic? How can you implement flow charts without gotos?) But I think the smartest programmers would have had no trouble making the most of present-day languages, if they'd had them. I don't doubt the truth of this point as it applies to the author, but I do doubt its generality with regard to others. But I guess people who have artifacts of the past built into their ideas of the present and future are reasonably bound to have difficulties. So, I guess I end up agreeing with the general point. I suppose I only fail to get why it is relevant.
Great Pseudocode: If we had the hundred-year language now, it would at least make a great pseudocode. What about using it to write software? Since the hundred-year language will need to generate fast code for some applications, presumably it could generate code efficient enough to run acceptably well on our hardware. We might have to give more optimization advice than users in a hundred years, but it still might be a net win. I doubt it. And certainly I don't find any convincing case here. Indeed, I don't even find any argument that leads me to believe that it might be true.
As of Today Now we have two ideas that, if you combine them, suggest interesting possibilities: (1) the hundred-year language could, in principle, be designed today, and (2) such a language, if it existed, might be good to program in today. When you see these ideas laid out like that, it's hard not to think, why not try writing the hundred-year language now? I'm afraid that Graham as still completely failed, to me at least, to make the case that a hundred year target is a better idea than some focus on the intermediate stages. But then we have argued for about thirty years that reasonable focus on the intermediate horizion is the most effective way to solve design problems, so I guess our views just differ at the core.

So I disagree with both of Graham's points here. I don't believe that one has much of a shot of designing the hundred year langauge, and further I don't see any reason to believe that even if you could, it would be a good idea to program in it today. I find this simply argument by unsupported assertion.

Having a Target When you're working on language design, I think it is good to have such a target and to keep it consciously in mind. When you learn to drive, one of the principles they teach you is to align the car not by lining up the hood with the stripes painted on the road, but by aiming at some point in the distance. Even if all you care about is what happens in the next ten feet, this is the right answer. I think we can and should do the same thing with programming languages. Gosh, that's not the way I learned to drive at all. I was taught something about placing myself with respect to both of my `side margins', getting a reasonably firm grip on where the right hand side of the car was. And aligning things on a distant objective all too often resulted in some `local problems' like the unfortunate tendency to bump the car in front of you. But then the analogy seems pretty labored anyway, so perhaps it is just best to forget it.
Note I believe Lisp Machine Lisp was the first language to embody the principle that declarations (except those of dynamic variables) were merely optimization advice, and would not change the meaning of a correct program. Common Lisp seems to have been the first to state this explicitly. Didn't the idea for this start with the earliest of FORTRANs. My impression was that optimization advice quickly fell out of favor, but perhaps Graham is actually interested in some other aspect of the problem than the one that occurs to me.
Close As the comments probably make clear, I don't buy Graham's argument. I think there are some important insights in his work, but I also think that the central argument pretty much falls apart---or worse, that there really isn't much of a central argument presented, rather just a series of assertions, many of which I find questionnable.

I think that the core of Graham's argument is that one should look to the future, indeed to the distant future, to find guidance for current activity. While I would heartily agree that looking past the `nose on your face' is important, any notion of looking into the distant future is an irrelevancy and a distraction from the important work which is really at hand. It makes an error that Saarinen neatly avoided when he suggested that we work with `the next larger context'. Saarinen didn't suggest we try to deal with any ultimate context. Merely one which was somewhat broader than the one we are immediately faced with. Broader yes. Too broad no.




© Copyright 2003 David Ness.
Last update: 2003-04-14 02:54:10 EDT