This is edited from a comment on [The Myth of the Super Programming Language] [0], which is a discussion of how many programmers seem to believe that some esoteric programming language could allow a team to outperform expectations by an order of magnitude. Edwards argues that people don’t really choose minority languages because they’re better; they just choose them because they’re more challenging, so they allow them to show how smart they are.
Unsurprisingly, I disagree. There are several interesting things going on here. Variations among programmers ---------------------------- One is that, as everybody agrees, variations among programmers trump everything. The original study (W. J. Erikson, Harold Sackman, and E. E. Grant, 1968 [1]) that everybody cites to show 10× variation among programmers also mentions that several of the programmers tested couldn’t even finish the test tasks at all. Try to compute the ratio of variation there, and you get a division-by-zero error. And we’ve pretty much all experienced co-workers who exhibit *negative* productivity — they introduce bugs, create ill feeling, distract other people from the important things, make promises the company can’t keep, copy-and-paste huge volumes of code, or add lots of unjustified abstraction. Most of us, if we’re honest and humble, can think of times we’ve been the guy with the negative productivity. So we can stipulate that programmer quality can account for any productivity ratio whatsoever, including negative productivity ratios. So clearly it’s more important to be a programmer whose productivity is relatively high than to choose the right language, or even a good language, as long as it’s possible to implement the system in the language chosen with a sufficient amount of effort. OK? Languages leading the way ------------------------- A second thing is that, when you don’t know how to solve a problem, your choice of language (and other tools, e.g. libraries) has a huge effect on how long you flail around before coming up with a workable approach. It doesn’t take that much effort to implement backtracking depth-first search in C or Java or Python. But if you’re working in Prolog, backtracking is one of the first things you’ll try. If you’re trying to solve Sudoku, this is likely to get you to a solution rather quickly. On the other hand, there are lots of problems for which this approach is too slow to be applicable, and it can take you a long time to figure that out. Of course, some languages tend to focus your attention on questions that don’t really bear on finding a way to solve the problem, like whether this field is going to be a `Foo&`, a `Foo*`, or a `Foo`, or how many bytes to allocate to which field, or which registers you’re going to pass your arguments in, or the precise lifetime of each allocated value — things that are crucial when the problem is to decode a frame of video by the time it needs to be shown, but maybe not for the majority of software. These are bad languages to use to explore problems you don’t know how to solve at all, unless the problem you’re having trouble with has to do with time or space constraints. On the other hand, like I said, if you know how to solve the problem, it isn’t going to take you fifty times as long to solve a big problem in C than in Prolog. (Relatedly, learning more languages teaches you more patterns of thought. Learning Prolog forces you to learn to think in terms of search, and when that’s useful, and how to control the exponential explosions. Learning ML forces you to learn to think in terms of pure functions on recursively defined structures. Learning Forth, Scheme, or Ruby encourages you to learn to think in terms of embedded domain-specific languages. Each of these turns out to be very useful in its appropriate realm, and you can of course implement them in your language of choice.) Low-level languages slow you down --------------------------------- A third thing is that, in fact, my choice of language *does* affect my productivity substantially, even though I’m the same person. In the last year I’ve written production code in Perl, PHP, Python, Objective-C, and JavaScript. I consistently found myself fighting with bugs I had written in Objective-C in decisions I didn’t have to make in the higher-level languages, and so everything just took longer than I expected. I’m often frustrated with the circumlocutions I have to use in JS to say something simple — a little bit when I’m writing the code, but much more later when I have to go back and read it in order to extend it. During that time, I’ve also written non-production code (“towering monuments of mental masturbation”, in Edwards’s terms) in Lua, Go, Forth, C, PostScript, and x86 assembly language. I find it relaxing to write code in C. I don’t have to distract myself from what I’m doing to look up functions in an API. It’s very clean and simple. I enjoy the mental orgasms. On the other hand, it’s slow going, and every time I have to track down a segfault, I am reminded of why software in the 1980s got new features so slowly. (Forth is even a little worse: no compile-time type checking, and it’s easy to introduce stack-effect bugs.) There are certainly some things for which the difference in program size between, say, Python and MIXAL is negligible. Even aside from the better readability of Python, its nicer error-reporting behavior, and its REPL, there are many more things for which the ratio is thousands to one. If you’re not convinced of this from your own experience, let me suggest that you try the exercise. Pick some simple problems to solve. Here’s a list of simple problems I’ve done or thought about recently: - using IP multicast to copy files between machines on the local network - downloading a series of web pages from webofstories.com - drawing some 2-D ray-tracing diagrams of optical systems - merging some text files whose lines are sorted in ASCIIbetical order at I/O-limited speed - summing the first column of an input text file - calculating the Haar transform of an input signal - generating fractals - losslessly cutting a JPEG file up into tiles and generating HTML to fit them back together - median-filtering the pixels of an image - uploading the latest photo from your digital camera to your web site. Try several of these in, say, C, and your high-level language of choice, switching up the order at random. If you're like me, you'll be amazed at how much more work it really takes to do this stuff in a lower-level language like Java or C, and how much harder it is to maintain the result. It's easy to forget these things. (I was going to mention Yossi Kreinin's [nomadic programmer phenomenon] [2], but I realize I don't really know how to fit that in here. Is Olin Shivers a canonical nomadic programmer? Dan Bernstein? Thomas Dickey? Julian Seward? Russ Cox? What languages do nomads tend to use? I'm not sure.) [0]: http://alarmingdevelopment.org/?p=392 "Jonathan Edwards, 2010-05-11" [1]: It was originally published on 20 December 1966 as SP-2687, “Exploratory Experimental Studies Comparing Online and Offline Programming Performance”, by System Development Corporation (no plural “s” on “System”), 32 pages plus four cover pages and DoD forms in the PDF I have. The original objective was to measure whether timesharing produced productivity improvements, but the immense variation in individual performance made this impossible to determine. A shortened version was published in the January 1968 issue of Communications of the ACM. There seems to be a copy at the Charles Babbage Institute, box 379, folder 13, United States National Bureau of Standards collection of computer literature, NBS# 6623961. I can’t find a version online at the moment, so I’m putting my copy online at <http://canonical.org/~kragen/sackman-erikson-grant-1966.pdf>. [2]: http://www.yosefk.com/blog/the-nomadic-programmer.html "blog post, 2009-08-06" -- To unsubscribe: http://lists.canonical.org/mailman/listinfo/kragen-tol