I sort of did this a couple of years ago without exactly realizing what I was doing. I learned a bunch of languages and played around with them for fun. Many were functional, many were not. I deliberately tried to learn languages I felt would be different from what I already knew, so I didn't even touch languages like C# or Ruby. It was a fun few weeks, and I got a better mental idea of a general framework of thinking about languages. It was effectively the "go meta" thing (the wording of that section of the post really resonated with me) -- I stopped thinking of languages as their own special snowflakes to be learned, and instead each language was a cocktail of features I already understood, wrapped in their own special-snowflake syntax (which doesn't take long to pick up). At some point I implicitly understood that it wouldn't be much effort to be useful a new language if I wanted to. I was an idiot student back then, so I never consciously realized this I think -- it just affected my decision making (e.g. "I need to code in perl to add this feature to my irc client? Doesn't sound too hard.")

This exercise became immensely useful, because while it doesn't give you the ability to write new codebases from scratch in $randomlanguage without needing to put effort into learning it, it does give you the ability to make nontrivial changes to codebases in $randomlanguage by looking at the context.

An explicit realization of exactly what skill I'd gained came a few years later at one of my internships. My own project was in Java/C++ with some GLSL, all languages I had used before. The project itself was very interesting, but my manager was super busy and I was finishing work pretty quickly so I'd often have nothing to do. A fellow intern had a very large C# project that I found pretty interesting. Involved a server-side backend, client-side app, phone app, and a lot of communication between them all. This intern was very smart, but had never had the chance to learn new languages or the general concepts used in building such things. He was learning, but would often ask us (me + another somewhat-bored intern) for help. Now, I didn't actually know C# at this point (none of us did). Never coded a line of it in my life. But I was able to pattern-match the code I saw with concepts I already understood and explain things. At some point I realized that I was teaching my friend a language that I didn't know in the first place. This blew my mind, and I gradually had a conscious realization that I could do this with most languages provided they didn't bring something too radical to the table.

---------------------

My personal list of languages I tell folks to learn are:

- C++ because it has so many unique features. This usually covers for C as well. D may be a decent substitute since it has a lot of overlap with C++s features, but they're designed to better work together. I suspect that learning D will not let you automatically hack on C++ code without learning C++ first, but the reverse would be easier.

- assembly

- A GCd OOP language like Java or C#

- Haskell

- Lisp

- Some flavor of ML. Rust or Swift can substitute here, but it's better to just pick up an ML.

- Something for the GPU (GLSL)

- Something with affine/linear types (Rust?)

- Something with dependent types (Idris -- I have yet to properly dig into this one myself)

- Javascript. Also has a lot of interesting bits.

- Some dynamically typed scripting lang like Python or Ruby.

It's important that you cover programming styles, not just features -- e.g. Lisp is there not because of its features, but because of the way you program in it.