Should I learn...

There's a lot of languages out there, and most of them have a lot of overlap over common problem domains. In principle, all languages being Turing complete, there's nothing stopping you from doing any task in any language. But in practice, there may be orders of magnitude difference (we're talking 100-1000x here) in how much time it takes to do a project in a suitable language vs. an unsuitable one. Among the joys you may experience by picking the wrong language are:

You shouldn't underestimate the importance of simple syntactical decisions and syntactic sugar. Learning a language and developing software both take a lot of commitment and hard work. If you don't enjoy your language, it will destroy your motivation, and it will become very hard to get anywhere.

Having to figure shit out on your own because all guides for topic X are written for other languages (translating example code you don't understand is so much fun!)

Committing hundreds or thousands of man-hours into a project, only to realize that you can no longer improve on performance or a feature set because of the design decisions your language made, and if you want to progress your only hope is to rewrite everything in another language first

Spending time and effort learning a language only to realize the job market for it is shit (if you have career goal as opposed to being a hobbyist)

To a novice, a summary of language features will not be much help. Even something as basic as functional vs. procedural is irrelevant if you have never programmed and don't understand well what these things mean. If you are just starting out, you have to be careful about who you listen to. There are many languages out there, and a lot of them are pretty good for solving certain sets of problems. But few are suitable for a newbie (as a newbie, you will be learning not just the language, but also general computation). The last thing you won't is to get trolled by some faggot engaging in language wars.

If you are experienced (rule of thumb: have you created useful software in and gotten paid for it in more than one language?) then the choice becomes much easier. Based on the languages you do know, you will probably already have a taste for certain features. Consider the languages you're already comfortable with - what do they do well? What would you change? The language you are considering learning will invariably be better in some ways and worse in others than those you already know. The question is do the pros give you enough to justify both the cons and the extra effort of learning a new language.

Ultimately, you should aspire to learn how to program, not to learn any given language. To wit, all programming revolves around making the computer do things: The computer know a small set of atomic, fundamental "things" which it can already do. It is your task, as the programmer, to define how these fundamental tasks should be combined with each other to perform new tasks. Depending on how the fundamental tasks of a language are chosen, and what rules govern their combination, some tasks will be rendered easy or difficult, intuitive or unintuitive.

Intrinsic vs. Extrinsic

When comparing the comparative merits of languages, we may divide them into two main groups: Extrinsic properties and intrinsic properties. Intrinsic properties are properties of the language itself, such as syntax. Extrinsic properties are everything that isn't part of the language itself: The community, the tutorials available, the libraries that have been written, how the language and its users are perceived, and so on. Basically, intrinsic properties are what you get if you were using the language in a vacuum, with nothing but a description of the syntax and a basic compiler.

Languages do not exist in a vacuum, but considering them in a vacuum may inform the bigger decision of which language is worth your time. We therefore make the distinction between intrinsic and extrinsic aspects for the following reasons:

Intrinsic properties are constant in time (at least until a new version of the language is released). Extrinsic properties are very much inconstant (who knows what language will be popular in a five years?).

Intrinsic properties influence extrinsic properties, but not vice versa (the exception is when language designers listen to what the community wants for the subsequent version of the language).

Generally, your decision should be rooted in the intrinsics, since as you can see, they are the key factor and they are the ones you will be stuck with so long as you use the language. But that's not to say extrinsic factors aren't important or should be ignored (this is in fact a very big mistake).

Intrinsic properties

For most languages that are designed without a specific purpose in mind, intrinsics will be fairly similar. They will not be glaring flaws or radical improvements. When languages are designed with a specific purpose in mind, they tend to have more drastic changes. Usually, if a specialized language is designed from a problem domain, that problem domain is very hard to deal with using more generalist languages.

Syntax

Syntax determines what the instruction you write in a language will look like. You should ask yourself:

How easy is it to remember commands in this language?

Is it easy to comprehend the syntax?

Can I code with just a basic text editor, or is it impractical without a sophisticated utility program helping you by highlighting code or generating repetitive code segments?

Are there too many keywords?

Is it legible?

Syntactic sugar

Syntactic sugar is the different shorthands a language can have, such as being able to say x++ instead of x == x+1.

If you happen to often do the things your language's sugar tries to facilitate, it can make your life a lot easier.

If the sugar does not help you, you can of course not use it, but remember that ignoring bad sugar will not make it go away. If your language has some retarded sugar that everyone loves using for some reason, it can make reading other people's code hell (this is also an example of intrinsics influencing extrinsics).

Paradigm (imperative vs. declarative)

Humanity has thus far discovered two ways of specifying instructions for a computer.

The imperative approach gives the computer a list of instructions. The computer executes the commands in the order given (although some of the commands themselves may involve altering the initial order). For example, to compute the circumference of a circle, you would tell the computer to first take the radius, then multiply it by two to get the diameter, then multiply that by a pre-computed approximate value of pi, then print it to the screen. There are dozens if not hundreds of imperative languages like C, C++, Java and many others.

The declarative approach simply defines what each thing means, and lets the computer put the definitions together. It can be difficult to make the calculations happen in a certain order, but because no order is specified, paralleling tasks to improve performance can be very easy. For the circumference, you would give the computer the formula for circumference, the formula for approximating pi (for example 22/7), and ask it for circumference given a radius. Note how I don't say "print to the screen" - communicating with the user can also be a problem with declarative languages. In practice, the main representatives of this class are functional languages like Haskell or Lisp.

In theory, these two styles are exactly equivalent in terms what programs it is possible to write in them. But in practice, they are very different, and can have a huge impact on how easy a given task is.

Historically, imperative languages have dominated, and have been regarded as easier to understand. Perhaps the idea of giving someone explicit step-by-step instructions is more intuitive to the human mind than systems of functions, but regardless, most people find imperative languages easier, and interest in functional languages often correlates with mathematical aptitude. If you don't know what you're doing, you should probably start with an imperative language.

On a deeper level, there is an interesting note about having two paradigms together: There are ways of essentially calling modules written in a functional style from an imperative program, and vice versa. It is probably better to nest declarative logic inside imperative logic: The two advantages of imperative logic are being able to enforce a sequence and easy interaction with the user. Both of these are most powerful when done at the top level of the program. The advantages of functional logic involve flexibility in solving a well defined problem - so they are well suited to acting as a specialized module.

In many modern imperative languages, it is actually possible to write almost declarative, functional-style logic (in particular, look for "lambda expressions"). Because the language is not designed with purely functional programming in mind, this may be impractical (difficult to debug, clumsy to type out, slow and unoptimized) but in some small but important subset of problems you can actually mix the two paradigms together.

Object oriented programming (OOP)

The basic logic of OOP is:

Everything is an object belonging to a class of objects

Classes have their own variables (fields) and behaviors (methods)

Classes are taxonomically related to each other, and can inherit and extend each other's functionality (inheritance)

With an OOP project, a significant amount of work is spent on class hierarchies defining which class has what components and what it inherits from. The actual functionality of the program is supposed to flow naturally from those. There's a lot of analyzing the problem into compartmentalized units that interact with each other.

This way of thinking is suitable for some problems. For example, when programming a GUI, it can be convenient to represent all the scrollbars, buttons, checkboxes and textfields as classes with shared behaviors. At other times, adding OOP may just make a trivial thing difficult.

Strictness

There's quite a bit of variance between languages in terms of how much detail they require. Say you want to define a variable to store a number. Some languages are very pedantic, you are required to specify what kind of number, whether negative values are possible, what the max value should be, whether it's a whole number or decimal, and how many digits to store if decimal. Other languages just let you define your number and never ask questions, trying to make reasonable assumptions about all the things you left out.

High strictness can be useful in two ways. First, it gives you better control over exactly what the program is doing. This helps with optimization: If you know a variable will never store a number bigger than 255, there's no point in using a larger format and wasting memory. Second, they force you to constantly think about every detail of your code, and may help reduce bugs (but not necessarily). Examples: C, C++, Java, Haskell (functional).

Low strictness is good when you just have a simple idea, and want to quickly get it working without getting hung up about the particulars. Unfortunately, some of those details you did not specify will eventually cause subtle bugs that will be a pain to fix. Examples: Python, JavaScript.

Strict languages tend to be good for production-level software where reliability, close adherence to specs and high level of optimization is necessary. Non-strict languages are good for prototyping and hacking together one-shot scripts.

Extrinsic properties

Documentation

Always check what books, tutorials and help forums (or how many questions on StackOverflow) there are for a language. It can be the best language ever made, but not being able to quickly Google simple questions can really slow down your learning.

Libraries

Learning exercises aside, these days it's stupid to write a program from scratch. A lot of common functionality like file I/O, working with arrays, sorting, math functions, graphics, networking, etc have already been implemented, and hopefully packaged as libraries. You shouldn't reinvent the wheel.

It can be hard to gauge the ecosystem of a language, but try Googling things like "How to do X in language Y" - do you get short, easy to read results which use well-maintained and well-documented libraries, or do you get a bunch of people writing their own unreadable hacks?

Examples:

For a while C# was a very good choice for making games thanks to XNA (unfortunately Microsoft stopped developing it when Windows 8 came out). XNA handles many things like keyboard/gamepad input, 2D/3D graphics, sound, game update cycles, framerate, assets and so on for you, and has nicely documented functions and plenty of good tutorials. C# by itself is a decent language, but not that great - XNA was what allowed a lot of independent games like Terraria and Bastion to be made with a small team.

Python has a few libraries that are so good that doing webscraping (BeautifulSoup, etc) or scientific computing (SciPy) in something else is just stupid at this point.

Platform

In principle any language can run on any platform, but it's another matter entirely whether your favorite framework is available everywhere (for example even though C++ works anywhere, DirectX is Windows-only), what performance will be, and how much support is available. Some platforms are dominated by a language:

The basis for Android apps is Java. You can get others to run, but all the tutorials you find will be in Java.

If you want to program for iOS, you have to use Objective-C (incidentally, a language useless for anything else).

Webapps are usually made in Python (Django), Ruby (with Rails) or JavaScript.

Browser games use Flash or HTML5.

Performance

I'll put this into extrinsic, because its depends a lot on implementation. Generally, anything with a VM will take a performance hit. Anything interpreted will always be slowpoke. Garbage collection, dynamic typing, all slow things down. Luckily, computers these days are so fast that performance usually doesn't matter. But in high performance applications (3D vidya, cryptography, statistical computation) you need a language suitable for systems programming. Functional languages can sometimes be much faster than imperative, because you can optimize some things very nicely in them.

Perception

If you want to program as a hobby, this is irrelevant, but if you want to get a job, it's worth carefully researching what is in demand where. For example, Python, C# and Java are the top 3 if you want to write trader bots on Wall Street. Java and C# are shit career choices because you'll compete with millions of third-worlders for low-paying positions.

Community

Some languages seem to attract more faggots than others. For a while, Ruby was infamous for its hipster fans.

Summary

Individual languages

Ada

Designed to catch as many errors as possible, as soon as possible

Pascal-like syntax

Excellent for embedded, systems, or realtime programming, but suitable for pretty much anything

Programming by contract in Ada 2012

Many advanced features like tasking, generics, and exceptions were built in to the language back in the 80s

Good support for proving code correctness, especially in SPARK variant

Verbose code

Lacking in up-to-date tutorials and documentation for beginners

Not used much outside of the defense and aerospace industries

Assembly

Terse, but pedantic as fuck.

Small programs are simple to write, but larger ones become an unwieldy and complex mess in most cases.

Based Motorola ASM, so many variants, so much serial port downloading.

x86 ASM is pretty neat too, also known as PC ASM. Pain in the ass because AT&T ASM syntax is the UNIX standard, and Intel ASM syntax is the DOS standard and they are so close but its the little things that are different. Enough different to be a pain in the dick.

Not portable. This is as close to the metal as you get without writing actual machine op codes. Each instruction IS a 1:1 mapping to a machine opcode. Each CPU architecture has a different set of instructions.

LINQ is a very powerful way of working with collections (lists/sets/arrays) and databases (if mapped to collections)

Visual Studio/ReSharper is very nice IDE for C#

3rd most popular language on StackOverflow, very active community with many experts

Mono

Open alternative to .NET started when .NET was closed-source (Mono framework allowing you to run it on GNU/Linux)

Implements almost all of .NET, but leaves out a lot of WinForms and WPF (GUI stuff)

Dubious legal situation because parts of the language are encumbered with MS patent

Erlang

Makes concurrency/multithread shit a breeze.

Uses a specialised VM that has a hard time crunching numbers, and an even harder time handling strings.

Golang

Also known as Go

Created by Rob Pike (one of the original UNIX guys) and some other engineers at Google

Mascot looks suspiciously similar to the Plan9 mascot

Is basically C with minimal extras, but with garbage collection, and some core language features to make it really good for concurrent programming (doing multiple things at once). Not really as fast as C, though.

Directory structure must be laid out in a certain way to build projects

Has an interactive tutorial at their website, and a go tool which allows you to pull from github, and package go, etc

Uses Goroutines for concurrency, which are like lightweight threads which are then fit into threads for more efficiency. The compiler handles the threads for you.

Haskell

Extremely expressive, offers abstraction capabilities near Lisp

Focuses on pure functional programming and type systems

Very rigid language, if you do something wrong, it probably won't even compile

Takes a lot of time to learn completely

Can be unwieldy for inherently stateful problems

Java

Very portable; compiling down to bytecode, which is then executed by the JVM

The language that made OOP commonplace

Some initial design decision have turned out to cause problems, but can't be fixed because of backward compatibility

Very large and enterprise

Huge libraries and a lot of software is written in it, including code from academic papers

Very verbose APIs

Receives a lot of undue criticism

Used to be slow many years ago, but these days is very fast

Can be convoluted to write in sometimes

Both the language itself and the core libraries are very bureaucratic

Is made fun of for the design patterns people use with it, and for the verbose naming schemes often used

Lisp

Family of programming languages which have the most notable features of using fully parenthesized prefix notation and being homoiconic.

Intially appeared in 1958.

Lisp is said to change the way one thinks about programming, because it exposes the abstract syntax tree to the programmer for modification and extension of the language itself to fit the domain-specific needs of a particular task.