This list hints at something interesting:
The intent behind the creation of a programming language does not always match up with the result, or the culture around it.
For example, you might say;
Lua: SOL (our data language) doesn't have enough programming constructs.
which is historically accurate, but in a modern context you might also say:
Lua: Game engines and other apps need a really easy to integrate, reusable embeddable scripting language library.
which is a vastly different problem that lua didn't necessarily set out to solve.
I'm delighted by the way that TCL-like languages and Perl-like languages grew towards one another.
The experience that motivates TCL: you'll be working on your compiled codebase and think, "damn - it should be easier to glue blocks of this together."
For perl - you'll be working in shell, and then move to awk, and find yourself using the function structures and ignoring the pattern matching. And you'll think, "damn, I wish this had more powerful programming structures in it".
In the middle you get ruby and lua, which are very similar, but came from opposites.
In an earlier draft of this post I wrote python and lua above, but then I checked some history. Interesting - it's kind of an accident that python evolution to challenge the shell/awk/perl scripting space. ABC was created from academic motivations. Python 1 didn't quite know what it wanted to be. If you joined python at 1.4 and stayed through the release of 2.0, it's easy to imagine that it would have evolved with a more functional emphasis than it did. By 2.2 (new classes) it had solidified as a objecty response to perl5.
Isn't "+." an ocaml thing rather than ML in general?
I think SML had overloaded numeric operators, though I think that's a special case (i.e. type classes are still better)
Yep, you're right :). I opened the Standard ML book, and there on p75 they list * :: num * num -> num. Then at the bottom they say each function declared as such really has two definitions, one with num replaced by int and one with num replaced by real.
So yes, +. is just an ocaml thing. Not sure about caml.
Haskell is a far cry from just lazy ML. Oddly enough, your summary of go would be far more appropriate for haskell, which makes go's concurrency handling look primitive.
Only slightly relevant, but an insight I had recently.
I'd noticed that all programming languages were tree-oriented. You kind of group logic into branches. This sounds obvious, but work with me here.
This reminded me of the early days of yahoo: it was a big directory (a tree structure). Then we had this revolution where everything became about loose data that was tagged. You'd have tagged data, and then search on the tags. This tag structure was better for scale than the tree structures we'd brought with us from personal computing problems.
I thought, "I wonder if you could build a tag-based programming language". And then I realised - that's what prolog is.
Typeclasses were probably a killer feature for Haskell. I remember using functors in OCaml and they were pretty sweet, but typeclasses let you "label" types with functions and values after the fact. Sure, ghc would complain about orphan instances (if you "labelled" the type outside of the file where it was declared), but it was so darn useful.
Interesting view of prolog. If you look at indexing and search as an alternative organizing structure, perhaps Wolfram Alpha would be the language which takes that paradigm. My understanding is that Alpha takes the "search" term and generates multiple programs corresponding to what you're trying to compute.
If we're going for why Python appealed to its early adopters as opposed to the actual motivations for creating it in the first place, something more like 'other languages are all hard to read' would be fair. You could even reintroduce the Perl rivalry in the form 'Perl is too hard to read', if you insist. But it really wasn't Perl's kludgeyness per-se.
I'm never liked this list, mostly due to Python but I think other languages are also incorrectly characterized. Guido worked on ABC and wanted something for scripting tasks on a Unix machine. Python was mostly inspired by ABC but some of the syntax was inspired by Modula 3.
Python is certainly not a reaction to Perl, I'm not sure Guido was aware of it when Python was born (they are close to the same age, actually).
> I think other languages are also incorrectly characterized
Agreed. This stems from a neat idea, but I think it's an after the fact rationalization (except for a few that are provably correct, like J). For example, C++ didn't stem from a direct frustration with C:
"Stroustrup found that Simula had features that were very helpful for large software development, but the language was too slow for practical use, while BCPL was fast but too low-level to be suitable for large software development."[0]
This list is cute, and provides good "taglines" for the languages, but I think it'd be met with a larger grain of salt if it hadn't been written by PG. :)
It would be nice if there was a date attached to this. It appears to be 10 years old judging by the list of languages and the sentiments attached (although time probably wouldn't alter the sentiments greatly).
For Ruby, I would suggest "Smalltalk doesn't like Unix" instead. What attracted me to Ruby is that it was a Smalltalk-style pervasive OO language that could be used for scripting and didn't require persistent images.
Go: C is too low-level, C++ is too complicated, and neither is adequate for concurrency.
(That's an attempt at summarizing Rob Pike and fitting it into Graham's framework, not necessarily what I believe, although I believe something close).
Had to add this because I thought it was fairly obvious, but all the other Scala mentions were either snarky or seemed to miss the core point of the title of the post : "What languages fix"
Scala : functional programming without leaving the JVM
Because enterprises have spent a decade or so building up JVM expertise in the form of Java.
Scala is really a multi-paradigm language, and that is arguably one of its major selling points. While you can use it exclusively for functional programming if you wish, object-oriented and imperative programming are equal citizens.
Scala is much more than a functional language, its more like Java done much better, not all of its useful features are functional. Maybe you meant clojure?
There is also an enhanced version that brought it a little further up to date. Problem is, people keep insisting that it must be wrong, because X doesn't descend from Y, etc. That's why the text at the top tries to emphasise that this is a graph of "developed because of a perceived short-coming."
Added in edit: Now submitted as a separate link for more specific discussion.
I would put it as "Rust: C++ is unsafe, and all other attempts to make C++ safe have made it too high level." (Alternately, "concurrent programming with data races is a kludge, and all other attempts to fix data races have ruled out too much.")
I don't think the historical evidence supports this. PHP was invented as a templating DSL for C programmers. I'd propose:
PHP (version 0): C is not an HTML templating language; Perl and Python are too heavyweight as embedded templating languages, given that all of our logic is in C anyway.
PHP (version N): PHP works fine, except it's missing function F.
...and so on, ad infinitum.
PHP doesn't really fit the paradigm of the original essay. It's hard to even pretend that PHP was deliberately designed as a reaction to other existing languages. Rather, PHP evolved. Hence, explanations of PHP tend to be circular: "PHP exists because PHP's design, documentation, and community were tightly focused on web publishing", or "PHP exists because it's backwards-compatible with PHP".
APL: Errors increase in proportion to the amount of code typed; therefore, decrease amount of code typed while keeping expressiveness and power unchanged.
Guy Steele didn't actually design Java. He was hired after the language was designed to write the spec. Of course, writing a specification exposed problems with the design, and those problems had to be fixed, so he had some influence on those parts of the language.
Dragging out that quote doesn't really answer the question. What about Java makes it like Lisp? The ability to (painfully) implement closures with objects and vice-versa? That's also shared with every other OO language, includes ones that would not normally be considered Lisp-influenced.
What other OO languages? Ruby is Lisp-influenced for sure. :)
Anyway, the context is explicitly Java vs C++, not Smalltalk or Ruby or Python. I imagine if Smalltalk were the dominant platform this would've turned out differently. So let's do a compare and contrast.
Java has the following properties: methods are all virtual; single inheritance; inheritance isn't public/private; final instead of const; GC and references w/o memory alloc or pointers; a package system exists; generics instead of templates; no operator overloading. And Java 6 does have a limited form of closures, believe it or not-- you can access a variable declared as final with an anonymous inner class.
None of that is true of C++, and just about all of those substantially increase the complexity of the language. I don't even like Java, mind you, but after reading Effective C++ the influence of higher-level languages like Lisp was pretty obvious to me, even if Lisp might not have been the only or even primary influence on Java.
Maybe I'm overstating, and maybe there are other languages in between I don't know about. If you look at what's in memory at a given moment, how objects are connected to one another, and how they're connected to code, I don't think Java looks that different to Scheme; apart from continuations, macros, and TCO, you can write Scheme in Java if you're bloody-minded enough and don't mind your lambdas disappearing into masses of curly braces.
Actually, looking at http://en.wikipedia.org/wiki/History_of_programming_language... it turns out a lot of languages with the properties I'm describing came before Java, so while Java clearly descends from Lisp in a lot of ways, the connection isn't as direct as I was imagining.
Java is a cleaned up version of C++. The JVM is an implementation detail, albeit an important one. The language itself though is about removing the necessity to manually manage memory, but staying within the OOP paradigm (or the OOP paradigm C++ proposed).
For example, you might say;
Lua: SOL (our data language) doesn't have enough programming constructs.
which is historically accurate, but in a modern context you might also say:
Lua: Game engines and other apps need a really easy to integrate, reusable embeddable scripting language library.
which is a vastly different problem that lua didn't necessarily set out to solve.