There's an unfortunate tendency built in to human thinking called "commitment bias" (it's subtly different from confirmation bias).
Once we make a decision, even if we carefully weighed up the pros and cons of the alternatives, after deciding, suddenly the pros of our favoured choice seem more important, and the cons seem less significant, while the pros of the rejected alternatives seem less compelling, and the cons insurmountable obstacles.
Oops, got the name wrong. The phenomenon I'm talking about doesn't have a cute name, it's called "Choice Supportive Bias"
Also, Wikipedia's list of cognitive biases is awesome.
And yes, I could have edited that mistake out prior to publication, since this is a new stream. I left it in, in the spirit of the site.
Anyway, this is one of the factors that helps escalate technical disagreements into flame wars: we choose a technology, and start thinking in ways that discourage the possibility of even considering that we might have made a mistake in our choice.
An attitude I try to cultivate in a deliberate effort to counter this is one of "respectful dislike".
There are really only two programming languages I particularly like: C and Python. I like them for very different use cases and very different reasons, but I do like them.
There are an enormous number of languages I simply have no opinion on, because I've never actually tried them, or even looked at them.
However, there are also a number of languages that I genuinely dislike, or which I strongly suspect I would dislike if forced to use them for some reason.
The trick is to still respect those languages, and the things people have achieved with them, even though I personally dislike them.
Perl, I really dislike. I suspect this is for the same reason I can't stand vim and very rarely use keyboard shortcuts for anything: I thoroughly detest learning anything by rote memorisation. My brain just doesn't work that way.
There's More Than One Way To Do It is anathema to my style of thinking. To read other people's code, I'd either need to remember all the ways, or else have the docs open permanently. Neither is a palatable option.
However, I respect Perl. As a tool for text manipulation, including constructing pipelines from command line tools originally designed for human interaction, it is still unparalleled.
And it's good enough as a general purpose language, that people have built quite sophisticated tools with it, that perform the job as requested.
Not only that, but the success of CPAN is still the gold standard for language specific distribution archives.
Ruby I suspect I could actually learn to like, at least at a language level. However, it's too similar to Python in scope and expressiveness for me to have any great drive to do so.
I also believe it replicates some mistakes from Java (by disallowing the option to create purely procedural interfaces), and has a culture without sufficient influence from large scale system designers (to successfully scale applications to large numbers of developers, action at a distance needs to be strictly limited. You can enforce this at a language level, as in Java, make it a cultural convention, as in Python, or else handle it at an architectural level by breaking your system up into independent components with standardised protocols between them. These aren't mutually exclusive options, and defence-in-depth principles apply).
However, there are also many very elegant ideas in Ruby (especially the blocks concept), and it is clearly being used successfully for many applications.
Java is one that comes in for a lot of hate from the web community. I think a big part of that comes from different concepts of what it means to have a "big team".
Scaling up applications is hard. Mostly, this is due to the need to maintain a coherent application architecture, while still minimising coupling between components.
The approach the dynamic languages tend to take to this problem is to use something other than ordinary calls between components that need to have low coupling, with a message or task queue of some kind being a very popular option.
Java is designed to allow a single code base to be scaled up, with the compartmentalisation enforced at the language level. However, this ability to handle high end complexity comes at a very high cost: the minimum level of complexity in Java is very high.
You certainly can't realistically use Java as a prototyping language, but as an implementation language, it's got a lot to recommend it.
However, I also believe that very restrictiveness is the cause of Java's culture of bundling patched versions of dependencies. The encapsulation enforcement is so effective that you really have no other choice if there's an error or missing feature in a dependency that you can't workaround. In the dynamic languages, you'll often have the option of creating a runtime fork via monkeypatching, so there's no need to actually patch the source code.
Definitely still more to ponder here, C++, of course, but also brief notes on other languages that I haven't used extensively, but still have had some exposure either to the language, or to its concepts (including Haskell, Erlang, Matlab, Lisp)
For an explanation of what I mean by prototyping vs implementation, see slide 19 in my presentation on Path Dependent Development