After programming for 30 years (and upwards of 20 languages) I've come to believe that you really only "need" to learn 4 languages to complete your Jedi programming skills and become a master. You need one each from the following categories:
"Machine" language - this is anything turing complete that's close to the hardware, ie that forces you to think about and understand the underlying circuitry. Candidates: Assembler, C.
Static/Imperative "Object" language - put this one off for as long as you can, for it is easy but not simple, and will ensnare your mind with the belief that you are special because you are among the elite priesthood of programmers who can grasp levels of complexity mere mortals dare not even dream of. Down this path lies years of frustration, all in service of the darkside. Chances are that this category will be forced upon you first, by naive, shortsighted fools who little realize the evil they are spreading. Learn only what you need to disable the tractor beam and escape with the Deathstar layout, so that when the time is right a well planned rebel assault may remove this abomination from the universe.
Candidates: there are no candidates here, as that implies choice. One of these languages will be heaved upon you whether you like it or not - C++, Java or Visual Basic (if the darkside is particularly strong in you).
Dynamic "scripting" language - this is for that category of problems where most of the needed abstractions are well understood and well tested. Using them should involve as few words as possible.
And finally, what should be every programmer's last language,
A "language" language - these are usually known as Lisps, but I think both Alan Kay's original bootstrapping Smalltalk and Forth are acceptable here. The key feature is having a small core of concepts that can be infinitely composed into higher abstraction commands that are treated no differently from the compiler's perspective. Once you have this power, all of the interesting behaviours of languages like Haskell, Erlang, Prolog, etc, are available to you.
Candidates: Scheme/Racket, Common Lisp, Clojure, Smalltalk, Lisp.
I rarely comment here, but your excellent post deserves to be recognized. I'm someone who has thought a good deal about starting a consulting company but never managed to convince myself the risk/reward numbers would work for my life situation. Your richly detailed and honest perspective is much appreciated. Thank you.
One thing that can be a negative irritant for new users is how far the esc key is and how often they have to reach for it. Vi wasn't designed that way. It was designed for keyboards that had esc where the caps lock key is on modern keyboards. One solution is to map caps lock to the esc key. Another solution, the one I prefer, is to map ii instead. This can be done with the following in the .vimrc file:
imap <silent> ii <Esc>:let &insermode=0<CR>
This doesn't work so well if you are frequently editing files on multiple servers you can't edit the .vimrc file on. But for your local environment it'll make going in and out of insert mode a lot more efficient.
I'm dead used to using ii now so I'm probably not going to switch, but others have pointed out kk may be a better choice, due to greater distance between keystrokes/mode. Indeed, about one in ten times I hit ii when I don't need to.
"Machine" language - this is anything turing complete that's close to the hardware, ie that forces you to think about and understand the underlying circuitry. Candidates: Assembler, C.
Static/Imperative "Object" language - put this one off for as long as you can, for it is easy but not simple, and will ensnare your mind with the belief that you are special because you are among the elite priesthood of programmers who can grasp levels of complexity mere mortals dare not even dream of. Down this path lies years of frustration, all in service of the darkside. Chances are that this category will be forced upon you first, by naive, shortsighted fools who little realize the evil they are spreading. Learn only what you need to disable the tractor beam and escape with the Deathstar layout, so that when the time is right a well planned rebel assault may remove this abomination from the universe.
Candidates: there are no candidates here, as that implies choice. One of these languages will be heaved upon you whether you like it or not - C++, Java or Visual Basic (if the darkside is particularly strong in you).
Dynamic "scripting" language - this is for that category of problems where most of the needed abstractions are well understood and well tested. Using them should involve as few words as possible.
Candidates: Ruby, Python, Perl, Lua, bash (or any bourne shell derivative).
And finally, what should be every programmer's last language,
A "language" language - these are usually known as Lisps, but I think both Alan Kay's original bootstrapping Smalltalk and Forth are acceptable here. The key feature is having a small core of concepts that can be infinitely composed into higher abstraction commands that are treated no differently from the compiler's perspective. Once you have this power, all of the interesting behaviours of languages like Haskell, Erlang, Prolog, etc, are available to you.
Candidates: Scheme/Racket, Common Lisp, Clojure, Smalltalk, Lisp.