Do we really need another programming language?

Yesterday, a group inside Google released a new programming language called go. Among the many comments on the new language, I noticed a number of people rhetorically asking if there is really room for more programming languages. I’ve seen the same sentiment expressed before, seemingly whenever someone releases a pet language (Arc, Factor) or rediscovers an older programming language (Smalltalk, Erlang, LISP).

I’m convinced that there is, in fact, room for more programming languages.

I recently read The Mythical Man Month, the 1975 classic about software engineering. Two things stuck out at me. First, that compared to programmers in 1975, programmers today are spoiled by hardware. Many software constraints, like memory and CPU speed — let alone the size of the program on disk — are not issues worth much thought for many software projects. There are of course exceptions: low-level systems code, graphics, data-intensive calculations (in other words, “the fun stuff”) — but in general, application programmers face far fewer constraints than they did 35 years ago. The second thing that struck me is how comparatively little programming has changed since then. Despite the loosening of constraints, we still write applications that, say, directly use pointer arithmetic and manually allocate and deallocate memory.

It’s not just C++, either. Here’s an experiment. Consider the last program you wrote in any language. Imagine you had to describe, in plain English, your program. The description must be complete enough that another programmer could read it and produce your program. Not your program exactly, of course, but one that satisfies the same requirements your program does. (If you actually try this, you may get something that looks like it was written by a lawyer who charges by the comma. That’s fine.)

Now compare your description to the program’s source code. The source code is almost certainly several times longer, less intuitive, and less descriptive. And yet, if your description is precise enough, all the source code does is communicate the same idea to the compiler.

There are two main things that differentiate the source from your description. One is that the source is designed so that a computer can parse it. This amounts to having some regular structure and a well-defined meaning to all the symbols. The other difference is that the description defines what the program should do, and the source describes how. These differences both contribute to the verbosity of the source code, but I suspect the latter contributes more (consider how concise formal math notation can be, despite having structure and being well-defined).

The obvious way to make a language more expressive, then, is to make it more declarative — to describe what the program does, not how it does it. Ideally our programs could be completely declarative. We could translate the description we wrote for the experiments a few paragraphs back into a more formal language, without adding any implementation details. Then we would have a compiler that created a program which satisfied our description and produced an executable. This type of programming is actually possible in certain, constrained domains (SQL and Prolog, for example), but unfortunately there isn’t a good general algorithm to translate any program we describe declaratively into machine instructions.

The best we can do, then, is to give imperative languages more declarative features. In fact, many high-level language features fall under this category. Take continuations, which let you say “resume code at this point” instead of how “store these pieces of state there, then restore the state and return here when called”. Or list comprehensions, which let you say “give me a list satisfying these properties”, rather than “loop through these elements and do that to them, discarding them if this is not true”. Or iteration constructs, which let you say “do this stuff for each element in that”, without specifying that space must be allocated for a counter, how to look up each element, or that the counter is incremented after each element.

All of those concepts have existed for decades. When available, they make code easier to write, understand, and modify. But even today, if you want to develop a native, cross-platform application, you have to give them all up or resort to using a relatively obscure language like Haskell.

It’s unfair to expect C++ to evolve to support these features, because it has decades of legacy code that it must be backwards compatible with. The language must be improved by either breaking legacy code or adding language features in an awkward sort of tacked-on way. Neither works very well, so the language evolves slowly or not at all.

I don’t mean to knock C++; sometimes it’s exactly what the problem needs. But I think a lot of programmers’ time is wasted solving high level problems with low level tools.

I’m doubtful that any one language will ever be the right tool for every job. Certain abstractions work well with certain domains (continuations with web programming, the actor model with concurrency, etc.), and abstractions that are baked into the language tend to have advantages to those that aren’t.

That’s why I welcome new programming languages. And as long as programming languages are less expressive than written English, I’ll keep welcoming them.

This entry was posted in Programming. Bookmark the permalink.

19 Responses to Do we really need another programming language?

  1. Rudolf O. says:

    You should take a look at Dijkstra’s work. In one of his books he says, “…It was slightly overlooked, however, that by expressing structure via syntax, this structure is only given very indirectly, i.e. to be derived by means of a parsing algorithm to be applied to a linear sequence of basic symbols.”

    So programming languages are just one way to indicate structure. They’re notation, and just as in mathematics, there are different notations to represent different ideas.

    There will always be room for more languages because of this.

    Also, “Imagine you had to describe, in plain English, your program. The description must be complete enough that another programmer could read it and produce your program.”

    With Literate Programming you do precisely that. Might want to give it a try, it’s a tiny bit helpful and at least better documentation results from it, if not better programming.

  2. Lee says:

    For languages that fit more with what you’re talking about, you should check out “design by contract” and the language eiffel. Also Kowalski’s Algorithm = Logic + Control reflects what you are trying to say.

    Interestingly, I’ve used much of the same reasoning to justify the programming language that I’m trying to make (even though it’s on the backburners for now). I, too, believe programming languages and legalese should overlap and eventually combine. Here are some other thoughts on the matter:

    http://lchou1.blogspot.com/2008/06/goal-achievement-programming-language.html

  3. John Farrell says:

    I think the argument is simpler than this.

    When people ask you to justify progress and advancements in technology just bring up the Model T Ford. Worked fine right? Why bother making a new kind of car?

  4. James says:

    “Now compare your description to the program’s source code. The source code is almost certainly several times longer, less intuitive, and less descriptive.”

    I was honestly expecting you to say the opposite. In my experience, source code unambiguously defines an application far more concisely than natural language.

  5. Richard B says:

    Google for Domain Specific Language ;)

  6. George Wolfe says:

    Your correctness of your observation about ordinary english and source code depends, of course, on the language. Look at a function I wrote in Mathematica, which takes a list of cusips, selects their monthly returns from yyyymm1 to yyyymm2 as a subset from a much larger set of returns, converts the monthly returns to the form 1+return/100 (as in beginning value * (1+r/100)= ending value, gets the product of the series, and passes back all the products as a list.

    I don’t think this is the greatest description – a really clear one would be longer. It seems to me that the Mathematica code is much easier to understand than my description. Maybe my code looks more clear to me then to others because I wrote it. But, I think Mathematica is a superior language, and while reading your comment, it occured to me that such a comparison might be interesting to you (since not many people program in it).

    ‘dates’ (a 1d list) and ‘returntable’ (a 2d list) already have their values when the function is called.

    wealthMultiplier[cusips_, yyyymm1_, yyyymm2_] := Module[{},
    b = Position[dates, ToString[yyyymm1]][[1, 1]];
    e = Position[dates, ToString[yyyymm2]][[1, 1]];
    returns = returntable;
    returns[[All, 2]] =
    returns[[All, 2]] /.
    Map[(# -> "drop") &, Complement[returns[[All, 2]], cusips]];
    returns = Select[returns, #[[2]] != “drop” &];
    returns = Drop[Drop[returns, None, {e + 1, -1}], None, {1, b}];
    returns = returns /. {Null -> 0};
    wealthrelatives = Map[(1 + #/100) &, returns];
    wealthmultiplier = Map[Fold[Times, 1, #] &, wealthrelatives]
    ]

  7. George Wolfe says:

    Looks like I copied and incorrect version of the function. The correct version is:

    (snip — Paul)

    Can you replace the first example with this one? (sure, done — Paul)

    I guess my point in making this post was that code can be terse and readable.

  8. George Wolfe says:

    Final comment. Give the wrap around problms, and other aspects of code that have nothing to do with my point (for example,the conversion of yyyymm1 and 2 to strings – ToString[yyyymm1]), the code isn’t clear after all.

    The function could be much more brief. For example, in the last line, ‘wealthrelatives’ could be replaced with Map[(1+#/100)&,returns], and then the preceeding line wouldn’t be necessary. The same is true for the series of transformations of ‘return’. But if you keep wrapping functions around functions the code does get less clear, and I’m still working on this code so I’m keeping it simple.

    Maybe all of this Mathematica specific discussion isn’t of much interest you and your readers. If so, I apologize.

  9. Evan says:

    Great thoughts. Thank you for this.

  10. “we still write applications that, say, directly use pointer arithmetic and manually allocate and deallocate memory”

    I was surprised to see you write that, I haven’t written a program that does that since we were forced to as a history lesson in college (early 2000).

  11. azgolfer says:

    No, as soon as NewSpeak is finished we can all just write code.

  12. dan says:

    Yes, we do need another language – but Google Go isn’t it.

  13. vix612 says:

    Considering your last sentence is FORTH from Charlie Moore the most recommended for you – it makes you possible totaly concentrate on the problem, but maybe you wouldn’t like it because of more thinking than writing on first trials with that.

  14. my understanding is that Haskell is considered Declarative (although not massively popular and a bit different from imperative languages)

  15. George Wolfe says:

    The discussion should be based on systematic framework for evaluating languages (eg, en.wikipedia.org/wiki/Programming_language). Languages have different features: typed/untyped, procedural/functional, etc. Consider a multi-dimention matrix all possible combinations of features. We could argue which cells need to be filled and why, but perhaps we only need specific cells to be filled and only one language in a cell.

    Maybe we need only a few very different languages. Maybe some languages would be for programmers operating at a particular level of sophistication. But this discussion need a framework. Thoughts?

  16. Rob Schatz says:

    Speaking of memory limitations, this brings back memories…

    http://www.classic-games.com/commodore64/64doc.html

  17. David Wright says:

    It is amazing the number of “programmers” today who have no knowledge of programming language, efficiencies and how to document and test their code.

    I worked for a web development agency and on one of the eShops, the server would lock up after about 50 sessions! (So they had a farm of servers.) By optimising the queries and optimising some of the code, especially if() statements, the servers could suddenly handle a couple of hundred sessions each.

    Using caching pushed it up even higher.

    Little things, like always testing the positive in an if() statement, not the negative (if possible) are lost on many modern programmers.

    Do we need new languages? Not necessarily, but if they are optimised for certain tasks or open up a new way of doing things, then there isn’t any reason for not having them. Developing a language for the languages sake or because people don’t want to use use other people’s languages (Microsoft are culprit number one here with J++ and C#, C# isn’t that bad, but it was a language for political reasons more than anything else).

    What we do need is to teach programmers how to code properly! And not just designing and documenting their program BEFORE WRITING ANY CODE, but also how to best optimise that code.

    I am now working on a site where the hardware dates back to 2002 and even a fully patched Windows XP SP2/3 is too much for the hardware, without getting a fully patched Office 2003 to run on it! Add in a current A/V software and the machine grinds to a halt – a bad one was a month ago, the AV company put out a patch, where it suddenly needed 30MB RAM to run; the previous patch used 8MB. On my new Toshiba laptop, with 4GB RAM and Windows 7 64-bit, I didn’t notice a problem, but the users on a 1.2Ghz Athlon with 256MB RAM complained that their machine was taking nearly 10 minutes to boot up, one user needed nearly 40 minutes for his machine to load Outlook.

    The next version dropped the memory footprint back down and the machines work reasonably again and I am upgrading memory, where I can. But the developers should be forced to use the minimum specification machines to test their code, before it is released (getting unit and system testing out of the way quickly on a well specified machine is all well and fine, but it still needs to be tested against their own minimum specifications!)

  18. Dave Jones says:

    “The obvious way to make a language more expressive, then, is to make it more declarative — to describe what the program does, not how it does it.”

    Declarative programming has been around for years. You even mentioned a declarative language in your article – Erlang. And whilst declarative languages (such as Haskell or the Mathmatica example) are useful in functional, mathematical and logic problems there has yet to be what I would consider a really good “general purpose” declarative language.

    I believe this factor, combined with the way computer science is taught and the already existing wealth of structured programs out there, are the reasons why declarative programming has not taken off.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>