19 comments

[ 3.0 ms ] story [ 49.5 ms ] thread
I think being too strongly tied to any one language/platform is really limiting your horizons.

Staying in your comfort zone (while obviously comfortable) can make programming seem very tedious as you kind of end up banging out the same old code over & over.

Try a totally different language for a while & when you come back to your particular Blub you might find your style has changed for the better.

I think that a serious programmer should know at least 10 different programming languages, including but not limited to (don't learn them in this order):

1) Assembler - preferably more than 1 CPU architecture. You _must_ know assembler in order to be able to reason about performance and computer architectures.

2) C - It's the most used systems programming language and will stay relevant for at least the next 10 years. Knowing what kind of assembler is emitted from C is also useful.

3) Java/C# or another flavor of Blub that works with a virtual machine, garbage collector and so on. Not really a family of languages with the most educational value but widely used

4) Lisp. Any Lisp. And some theory in lambda calculus.

5) Brainfuck. I'm not kidding. Brainfuck is to Turing machines as Lisp is to lambda calculus. Knowing how to program Turing machines with pen and paper is also useful.

6) Prolog or another logic programming language, like the one used in SICP. A whole new and different model of programming. Will blow your mind, guaranteed.

7) Ruby, Python or Javascript. A dynamic interpreted language.

8) Haskell or another functional programming language. ML dialects or Erlang might do, but I recommend Haskell for it's lazy evaluation semantics.

9) (edit) A stack based language like Forth or some of it's descendants.

10) Pick any language that will introduce a previously unfamiliar concept to you

11) Optional: Perl. I don't know anything about Perl but some people swear by it. That's a reason good enough.

Before you ask: yes, I do know every language in this list and many more. No matter what language you use to earn your livelihood, learning a language or two more will make you better at it.

I've never heard that perspective on Brainfuck before and have thusly avoided it as it seems, well, really hard & impractical.

Thinking of it as an abstracted turing machine is intriguing though. Do you know any resources on tackling the subject?

There's really not a whole lot abstracted about it. It is really hard and impractical for actually accomplishing anything, but it's also pretty easy to see how it maps to a Turing machine if you know what the actual definition of a Turing machine is.

That kind of thing I learned in a class: a textbook on computational theory is probably what you want, and as far as I know there are only a couple of those. I used this one: http://www.amazon.com/Introduction-Theory-Computation-Michae...

You don't mention any stack/concatenative languages explicitly - is that just an oversight, do you feel there's less to gain from them than the others explicitly listed, or did you leave them out for some other reason?
Good point, I missed this entirely. A Forth-derivative of some sort would be useful.
> Brainfuck. I'm not kidding. Brainfuck is to Turing machines as Lisp is to lambda calculus. Knowing how to program Turing machines with pen and paper is also useful.

... why? when was the last time that turing machines were useful to you?

The last time I've used Turing machines was when I was trying to build one in Minecraft using redstone and pistons.

But in general, Turing machines are a useful mental model when thinking about the fundamental nature of algorithms as well as when trying to reason if some non-trivial problem is computable or not.

And in general, knowing Turing machines and being able to write Brainfuck is exactly the kind of mental game that will help you think and approach problems in a new way.

And besides, writing Brainfuck is a helluva lot of fun!

It's not the doing that matters, it's that abilities that get sharpened.

No, I'm not going to be specific, because it's different for every person, but learning things like this help, even if you never actually use them as they are.

Doing calculus has helped me because it improved and shaped the way I think about how things evolve through time and space. Learning topology has helped me because I can picture inter-relationships as weird spaces, not just as lists of rules. Learning to juggle has improved my spatial awareness, and my abilities to gestalt patterns.

I don't differentiate or integrate on a daily basis. I don't prove theorems about metric, Hausdorff or Baire spaces, and I don't stand up on stage to perform as a juggler for audiences. Nevertheless, the learning has had beneficial effects elsewhere.

Sometimes it's not the skill itself that matters, it's the learning of the skill. To think otherwise is to tread an overly narrow path that leads to looking at everything new and saying "When am I ever going to use this?"

Brainfuck just might be the easiest language to actually implement. It's a learning experience and can provide a minimal understanding of how programming languages work. I'm sure someone can write the whole language in one line of Perl. The programs may not be pretty, but neither are programs written in lambda calculus.
I think it's a pity that you focus on general purpose programming languages. In place of perl, I would put

11) A domain specific programming language.

Perl could be an example (text manipulation) but could also include R (statistics), Frink (units of measure), etc.

Arguably, Prolog would fall into the category of domain specific languages.
True. While I'm not experienced with Prolog my impression is that it's often embedded in other languages, which I see as a very positive thing.

Beyond simply knowing a large amount of languages I think it's important for a programmer to be proficient at getting different languages/environments to operate together, as this opens up the ability to use domain specific languages. So, kudos, Prolog is probably a perfect example of this.

I've recently dived into Perl. Its most powerful feature, in my relatively short experience, is that it provides powerful semantics for everything - text manipulation, symbol table manipulation at runtime, packages, etc - and it also just gives up and assumes it's on a Unix system (hence the power as a "glue" language). Additionally, you can define new subroutines at run-time and replace most any part of the language at a whim. It's fast, and there is a very sane and simple subset of the language that's very readable and easy.

It is not, however, terribly sexy, and the cult of personality around Wall has turned off a few people I know. I am continually surprised at the simple solutions I can get out of Perl (and the complexity I am allowed to work with should I choose to).

Ten languages is a lot. Someone who tries to learn 10 languages in, say, 2 years is going to come out of that period not having really leaned any.

Here's my list. Ideally, each would be given 2000 hours of effort, or approximately one full-time year. So this is not a bucket list that could be kicked off in a few months.

1. Start with Python because it's easy to get to the point of doing useful work with it. You'll be able to write non-trivial programs quickly, and there are lots of libraries. Python and Scheme are great at getting out of the way when you're starting out, so you can concentrate on learning how to program rather than irksome details, and Python has better libraries.

2. Learn Lisp seriously. Read On Lisp or SICP. Which Lisp? Any will do, but I'd say Clojure's probably the most useful language for this purpose; you also pick up the Java ecosystem in the process.

These are prerequisites. Until you understand functional and imperative programming both, you don't understand programming. It's also worthwhile as an exercise to do FP in an imperative language and IP in a functional language just to get a feel for when breaking the rules (which real programs have to do all the time) is appropriate.

3-7 are "advanced topics" and can be done in any order. Listed in declining order (in my opinion) of importance.

3. A strong, statically typed language like Haskell or ML (Ocaml or SML). I'd start with ML (simpler, more elegant) and progress to Haskell later on if type systems become a passion. ML is easier to learn and not as terse. Why is this item so high? Because static typing, once you learn how to use it, is immensely powerful. It doesn't obviate the need for unit testing, but it reduces debug overhead considerably and that's often the difference between being in "flow" vs. being bombed-out bored and confused.

4. C and X86 Assembler once you start wanting to learn more about the lower-level aspects of computing, which are important if you are writing performance-critical code. These are not the place to start, but they are important.

5. Prolog or a similar logic programming language. Really great not for the practicality of the languages, but in terms of how logical programming can change your view of programming in the abstract. This becomes very relevant in design and architecture, especially of databases.

Concepts, Techniques, and Models of Computer Programming does a good job of explaining the different models and programming paradigms, unified in a logical-ish language Oz. Worth reading, often called the successor to SICP.

6. A concurrency-based language like Erlang or Go. This is given low priority not because the subject is unimportant, but because you'll probably learn a fair amount about this in other items (e.g. Clojure).

7. Java or C++, not because these languages are good (they aren't) but because they give you a sense of what can go wrong in PL design, as well as "how the other half codes". Extra credit for figuring out why and how these things went wrong. These languages were designed by some really smart people; there's a lot to learn from an archaeological perspective about how smart people can come up with such bad languages, and how bad languages in practice affect the way people work.

Here is, in my mind, the #1 benefit of polyglot programming: it refines your aesthetic sense, and it also gives you a sense of intrinsic vs. accidental complexity, the former being the innate complexity associated with the problem being solved, and the latter being complexity imposed by implementation details. It's crucial to know the difference, because good software engineering is about exposing people who have to use your code only to intrinsic complexity.

Ideal engineering practice: write the "beautiful" program first that only presents the intrinsic complexity (logic of the problem being solved). If performance is an issue, then optimize, a practice that often imposes accidental complexity on the code. Put said accidental complexity behind an interface as much as possible.

C++ and Java force a lot of the accidental complexity into source code and in these languages, it's hard to pick up the difference between intrinsic vs. accidental complexities.

Polyglot should not be confused with generalists. There are many generalist programmers who drift through their careers, never becoming an expert in a field so they're easily swapped in and out, easily outsourced, and easily forgotten. Some of the specialists out there, can make some serious salary (e.g. 200-250k/year for those that can build high speed trading platforms, or 150k+ for the architects of the biggest enterprise software).

That being said, limiting yourself to one language will be equally as hurtful, as you are wearing blinders. Even if you don't know all the languages, learning why they did things (DRY, functional programming, etc) can make you a better programmer in Java or whatever language you are in. As you supplement that, you'll find overall skill increases across the board.

My personal opinion is about 1 a year will do just fine, give you enough room to learn more than a book/sample project worth, see where the language goes in a market, and give you enough time to use it for something meaingful.

Its good to hear about the advantages of being a polyglot programmer, but how about the disadvantages? I think the number of recruiters requiring X years of experience in Y still outnumber the ones who can recognize the value of a polyglot programmer. Career wise, is it smart to go this route?