Warning! I made this comment because I thought this was an amazing and informative blog post, but nobody said anything in the last 7 hours it's been posted... :\

As a result, I've decided to toss out some thoughts I've had about Ruby, programming languages, PL implementations, and Lisp lately.

This is a fairly interesting, dense, but accessible list of aspects of Ruby that make it hard to optimize.

An interesting counter-example in terms of relative expressive power vs. performance would be Common Lisp.

The main differentiator seems to be how accessible the expressive power is. Ruby just really doesn't demand much forethought or precision on the part of programmer in terms of what should be in scope, what data is getting passed around, how to even represent the data, let alone in memory.

That's saying a lot, given that the default data structure in 'classical' lisp is a linked-list, which is a pathologically poor choice for today's hardware for cache predictability. Thus why Clojure has emphasizes the generic sequencing protocols/API and tries to nudge people towards using vectors for everything.

This all adds up to a language that is "easy" and expressive, but not simple.

It leaves one to wonder why we haven't gotten much further in terms of raw expression and concision at a high and low level than Python, Ruby, and Common Lisp. There are others that deserve mention for being interesting and powerful (Haskell, Clojure, Io) but for various reasons/limitations/trade-offs aren't necessarily more concise/more powerful in the small (trivial example) or in the large (managing state, scope, composing code from afar).

Clojure and Haskell pick some smarter defaults for the scale-up to larger codebases, but don't do much to offset the loss in expressive power those trade-offs incur. I think the emphatic focus on immutability and keeping as much immutable as possible as is the case with Haskell and Clojure is the way forward, but only Haskell has really made any attempt to explore how to advance the power of expression in that mode.

Idiomatic Clojure code barely makes use of monads as it is.

To understand the scorn that Common Lispers have (I used to code primarily in CL) for Clojure, Haskell et al, it's important to remember that they principally care about what's possible, not about what's idiomatic, standard to the community/libraries, etc.

It has long been the case that you could write predominantly functional, immutable, expression-based code in Common Lisp. Many did. What Clojure did was formalize it, clean it up, etc.

Clojure didn't bring anything new to the table in terms of power. Not like Haskell's type system. I spoke to David Nolen recently about predicate dispatch and it seems as if progress on that front has even stalled.

The delay in progress on predicate dispatch is disappointing because I was going to use the predicate dispatch work as the "selling point" for Clojure for a few CL'ers I know. It would've been a genuinely distinguishing point as while there has been tons of work on predicate dispatch in Common Lisp, Clojure's core.logic foundation was shaping up to have a better API and be more composable.

Instead I'm left with nothing I'm able to recommend with a straight-face to an experienced Common Lisper who isn't interested in JVM integration.

So what's new? What do you really win with Clojure other than better libraries and community? Not much.

Oh and the uh...concurrency primitives? They're a canard. They're neat, they're designed excellently (being that it's Rich Hickey), but they're just not as impactful as other things are these days.

If single-node/instance performance was important, you wouldn't be able to do it on the JVM. If scalability is important, shared memory on a single node is irrelevant and it becomes a matter of implementing a partition tolerant database.

The concurrency primitives would've been more important in an alternate universe where we didn't use databases/data stores/filesystems for state management and synchronization and instead did Smalltalk stateful servers.

That didn't happen and it was an extremely bad idea and we live in a world where java.util.concurrent exists.

So the CL'er who codes like a bi-polar hermit doesn't care about Clojure.

You want to win the Lisp-community-at-large? Give them more power. It doesn't have to be the trivialized imprecision of expression that comes with something like Ruby. It doesn't have to be the minimalism of Io and Scheme. It doesn't have to be native continuations.

It doesn't even have to be Shen or Haskell-style static typing.

What it does have to be...is more powerful for the lone cowboy. It's going to be hard to convince a lot of them without really hitting a home-run on that one metric. Especially in a post-CLOS/Art of the Metaobject Protocol world.

I think Rich Hickey knew from the beginning he wasn't going to win a huge chunk of the CL'ers over. I don't think it mattered. I think what mattered is that people stuck in the Java enterprise universe could have their sanity-preserving escape hatch.

It's a mistake to believe Clojure was designed for CLers. It was designed to save Python, Ruby, and Java people.

A similar case of mis-targeting is Go. Go itself was ostensibly a "systems" language when it launched. They got called out on the absurdly inaccurate labelling so they've since repositioned it as a general purpose language. Which is accurate.

They thought they were going to compete with C++. That's nearly impossible until someone comes up with a true successor to C and C++. Anything that doesn't enable absolute control over memory and semantics will never succeed them. There always has to be the "bottom" where you can exert near-dictatorial control over the behavior of the computer. Many industries need this.

Go was never designed to enable that, it was designed to make writing simple code simpler. That's all. And it's good at that. I was surprised when people with the cultural wisdom and background such as Rob Pike were surprised that they were getting Python and Ruby people instead of C++ people.

The raw contempt Go programmers have for debugging and interactive programming is appalling. That alone turned me off completely to the community. Partly because the only reason for that attitude is some off-hand statements Ken Thompson made in Coders At Work and elsewhere. Cargo-cult at its most definitive.

Why would a C++ programmer move to Go? They lose control of the memory, for which they have many layers of abstraction they can resort to (malloc/free, new/delete RAII, unique/shared pointers, Boehm's GC which is basically equivalent to pre-Go-1.1 GC, etc.)

They also lose the benefit of their years of investment and learning in C++ which offers them a dizzying depth of choices in abstraction layers. This has obvious disadvantages. C++ is a terror to attempt to write safe and stable code in.

It is however, extremely powerful and the "pay only for what you use" is essential for systems programming. My personal preference is C since I feel like I'm not aiming a bazooka at my face, but as a Common Lisper I understand the appeal of the power they feel they get from C++.

Even if the 'power' in C++ is of a different sort than that which you get from Common Lisp.

People unwilling to recognize and understand the power, advantages, disadvantages, and design trade-offs made by "scary" languages like C++ and Common Lisp will never be able to fully learn the lessons borne.

So no, I'm not surprised Go didn't attract primarily C++ programmers. Not in the slightest.

It's mostly been Java, Python, and Ruby programmers...for various different reasons. Like Clojure.

Most of the programming languages of the last 5-10 years have been "sidegrades". Enhancements of accessibility, of cultural idioms, of extracting a different emphasis on a subset of semantics that previous languages supported.

Have we really advanced beyond Common Lisp, Prolog, Smalltalk, and C++?

What does it mean to make a language more powerful than those? Is there a limit to expressive power? What do languages like REBOL say about "normal" languages? What about APL?

On a parting note, the only language that I've felt has truly expanded my horizons and impressed me in the last ~5 years has been Haskell (although it's much older than that). That said, I feel Haskell is a spiky, uncomfortable urchin of a language that is highly optimized to a local maxima of expressing problems in code. I learned a lot from Haskell, but I'll never be more productive in it than Python or Clojure or Go or anything else.

Too awkward, if enlightening.