If you are only interested in using software you can stop here, the rest is for people that want to know how to make their own.
At this point you might be wondering how people keep track of all the rules and syntax, and all the sneaky traps like confusing 1 and 1.0 or = and ==. Well most modern programmers are lazy, in fact it could be argued that any programmer that is not lazy is also not a good programmer. So we have a lot of software that programmers made to make their jobs easier. The main one is the code editor or “IDE (short for integrated development environment). This is basically like word processing software for code. Just like word processing software, there is a spell-checker that tells you when you made a mistake. Some languages have really powerful IDEs, where the spell-checker is like a magic genie that tells you how all the syntax works, keeps track of indentation and brackets, tells you what variables and functions are available and even makes recommendations about how to format your code better. These tools are getting more and more powerful too as programmers find better and better ways to be lazy. You can write code in any text editing software you want, but why put in the extra effort if you can slack off? If you are looking at learning programming I recommend you find a language with a decent IDE. Some languages don’t really have one and you are on your own. There are generic software editors that have a lot of plugins and support many, many languages. Regardless of which language you want to learn, there should be something out there that at least has syntax highlighting so don’t be a masochist and just use notepad or a terminal. If you can’t find a full IDE the best generic ones are Visual Studio Code, Atom and Fleet. If you don’t like using a mouse, Linux users will also recommend Vim and Emacs.
As you may have noticed in the examples above, lines of code are usually indented to show scope . This means that things on a new indentation level are nested or ‘inside’ the thing preceding them. Many languages also use brackets to make this more obvious. Curly brackets {} are used in many mainstream languages so I will use those as an example.
if(something)
{
foreach(thing in someList)
{
var myVariable = 7
some other random code
…
thing.number = myVariable
}
print(myVariable) //this wont work
}
In the example above the print line will not work because the variable was declared in a deeper scope. Generally anything that is declared inside a scope is destroyed at the end of the scope. There are exceptions to this, notably Javascript has unusual scope rules. Most languages don’t require indentation and it is just a style choice to make it easier to read. The exception to this is Python, where if you get the indentation wrong the program won’t work.
Most languages that use brackets require them, so these are not optional.
There is some debate amongst programmers about whether it is better to use spaces or tabs for indentation. This is a weird phenomenon that some people take way too seriously. If you want to pretend to be a programmer and have other programmers believe you, just express an opinion about whether tabs or spaces are better as though it is super important to you. Be careful doing this however, as some people may refuse to talk to you or attempt to convert you to the other side.
Code style is all the things that don’t affect how the program runs, including indentation, but also things like where to use capital letters, where to use brackets when they are optional, how variable names are written and many more. Each language has its own set of style questions, and each language/programmer/company/project has its own answers to those questions. I can’t really help you out with this other than to make you aware that you should pay attention to these things, you should look up a recommended style guide for the language you are using or the company you work for, and you should be consistent. As with indentation, people take this quite seriously. If you are just making hobby projects for yourself you can do what you want but if you plan to work with others you should pay attention to style. Ask the people you are working with if you are unsure.
Also worth noting, most languages have a way to annotate code, known as comments. In some languages two slashes at the start of text means it is ignored, which I have used above. Other languages sometimes mark comments in other ways. Comments are just for writing messages to other programmers, or yourself in the future. The don't have any effect on the program.
Not all software does something by itself. S ome people (bless their hearts) build libraries, which are collections of code that others can use to make their own software. For example if you are trying to write a program that saves data in Json format (see Storing Data as Text above) and you are using C# (pronounced C-sharp), you should get the library Newtonsoft.Json. If you were using Python and you wanted to do complex mathematics you should get the Numpy library. One of the things that makes new programmers far less efficient than experienced ones is that they are not lazy enough and try to write the code themselves. Numpy has a function called plot() which you can just pass a bunch of numbers to and it draws a graph of those numbers on the screen. Do you really want to write thousands of lines of code to build your own graphical chart library from scratch? The trick is to think about whether the thing you are trying to do has already been done by someone before, and if it has, knowing how to get hold of their code so you don’t have to constantly reinvent the wheel.
This is not always as easy as it sounds however. First you have to get the library . This might be as raw source code, or as a compiled file. Many languages have a package manager which makes this process much easier, so you only have to learn the command to tell the package manager to get and install the library. Otherwise you have to learn how to include libraries in your particular language.
Once you have the library, you will usually need to actually add references to it in your code. Most languages do this at the top of the file with a keyword like ‘using’, ‘require’, ‘include’ or ‘import’ and then the name of the library. There is no single search term that I can suggest to find out how to do this but you should get some results with something like using libraries in <languageName> .
There are three basic levels of programming, and it is worth knowing the difference when you choose what language you want to learn. In the end most of the same skills and knowledge apply so it does not really matter which one you choose, but it will be extremely confusing to you if you learn one type, and then switch to another without realising the difference.
Assembly is the language that computers understand, well technically there is a level of abstraction between assembly and machine code but it is pretty thin . That makes it very difficult and time consuming for humans to program. Nevertheless it is possible to do, and there are some advantages. If you are good at assembly languages you can write code that runs faster, uses less memory and has a smaller file. This is good for things like robotics and microcontrollers where you are using very simple hardware. There is even a competitive hobbyist scene where people compete to make the smallest programs. One of the most impressive examples of this is a game called ‘ .kkrieger’ which is a full colour, 3D first person shooter complete with music and sound effects. The whole game is under 100kb in size. For reference this article is about 50kb, the Android game Candy Crush Legend is 12,500kb.
Assembly is generally specific to a certain type of processor so if you are writing it for one type of device, it probably won’t work on most other devices.
Assembly language is not generally recommended for beginners and in most cases a compiler (see below) can write better assembly than a human. But don’t let people tell you you can’t do this as a beginner if this is some thing that you think might interest you. It is a great way to really understand how computers operate on a base level. On the other hand, if this sounds intimidating and complex, it really is and you should definitely not let anyone tell you that you need to understand assembly to be a programmer.
The majority of serious mainstream languages are compiler languages . What this means is that someone made up an abstract high-level programming language and also wrote a program called a compiler, which will take programs written in that language and translate them into assembly language. This is generally done to make programming simpler and easier for programmers. These are the meat and potatoes of programming and if you want to make a career of programming you should probably have at least tried out one or more compiled languages as they are used extensively. Because it compiles to assembly it can be made to run on lots of different devices, but it needs to be recompiled separately for each one.
There are some sub groups here as well.
There are virtual machine languages. A virtual machine is a pretend computer that exists only as software, which runs on your computer. The reason people make these is too complex to get into in this article but it is actually quite a clever idea and has some interesting advantages. The compiler compiles the code not for a specific processor but for the virtual machine. The only thing you need to know as a beginner is that software written in these languages will run on more different types of device and won’t need to be recompiled.
There are also just in time languages which are kind of a hybrid of compiler and interpreter languages. The code is compiled into a kind of intermediate language which is neither machine nor human readable. This is then compiled into assembly while the program is running. The reason people make these is too complex to get into in this article but it is actually quite a clever idea and has some interesting advantages.
Interpreter languages aren’t compiled at all, instead there is a program called an interpreter which takes a program or a set of instructions and then tells the computer what to calculate while the program is running. This makes the process of creating software simpler because you run the code directly rather than a compiled binary file. It also means they run on any device that has an interpreter for that language available.
Each specific programming problem can be solved in a number of different ways. Unlike the types above, these paradigms actually make a big difference to how programming in the language works, and what knowledge you need to do it. Don’t worry about it too much though; whichever one you choose, there will be a huge overlap, and moving to another will be easier afterward. Again the main reason to know about these is so that if you get used to one thing, it is not too much of a shock when you try to switch. Don’t base your language choice on this section, there are much more important concerns.
There are actually dozens of different paradigms and many have sub-groups and sub-sub-groups. Most languages actually use more than one of them. I will only be listing some of the more common ones here as they cover 99% of the programming you are likely to get involved with. If you want to do a deep dive into this subject there is an incredibly wordy and technical description of every possible paradigm on wikipedia here.
Don’t worry if you don’t really understand these explanations, that is my fault. The goal is to prime your mind so that when these concepts come up again they are not entirely foreign.
Most modern programming languages incorporate multiple paradigms.
Imperative languages are pretty simple and just involve a series of statements that are executed in order. I think of imperative languages as the ones that don’t have a paradigm. You tell the computer what to do in a straightforward way step by step. The reason the more complex paradigms were created is that imperative programming does not scale well. To make a really large complicated program you need additional structure, and although you can build that yourself with any language, having specific structures built into the language make it simpler, easier and more reliable. Imperative languages are fine for getting started and learning the basics but it is really worth learning object oriented or functional programming if you want to work on real world software. Most languages allow imperative code; an imperative language is one that only allows it and nothing else.
Object oriented languages use custom types (see above) called objects (also called classes) which are created in the code and contain sets of variables (generally called fields and properties when they are used in this context) as well as their own functions. For example: if you are a game you might have a class called clothing, which has properties like name, warmth, weight, etc. It might also have a function called fold.
Specific instances of classes are created in code, usually with a new keyword like:
myShirt = new clothing()
Object functions and properties are called in a kind of chain with a separator depending on the language. One common separator is simply the full stop like this:
myShirt.Fold()
The way classes are declared varies from one language to another so there is not much I can say about it here.
One of the main useful features of object oriented programming is . This means I can create a new class called which is a sub-type of clothing and has all the same properties and functions automatically. It can also override some of these like the function, which is probably not a good idea with most hats.
The main reason object oriented programming is popular is that it is easy to explain and understand for non-programmers. It conforms to the way we generally categorise objects in the real world.
People who use pure functional programming languages are often quite condescending towards people who use object oriented ones. This is not unjustified but it is very rude and unnecessary. See discussion about choosing a language below.
Functional programming revolves around using functions as the core of all operations. Functions can be saved in variables and passed to other functions as arguments. This means I can do something like this:
function AddOne = (n) =>
{
n + 1
}
function PrintAndRepeat = (f, n) =>
{
Print(n)
var newN = f(n)
PrintAndRepeat(f, newN)
}
PrintAndRepeat(AddOne, 0)
This program would print numbers starting at 0, then 1, then 2 and going on forever. The first part declares a function that takes a number (n) as an argument and adds 1 to it. The next part defines a function called PrintAndRepeat which takes a function and a number as arguments. This prints the number (print generally means to write something in the console or terminal and is not really something people see in most modern graphical software, but it is useful for testing things) and then calls itself. A function that calls itself is called recursive. When it calls itself in this case it passes in the same function it was given as the function argument, but for the number argument it first calls the function with n as an argument, and then passes the result. The last line then triggers the whole system, it calls the second function with the first one and 0 as arguments.
The first time around the function gets 0 and then prints it. Then it calls the function it was passed with the number (adding 1 to it), then it calls itself with n=1. Then it starts again, printing 1 and then calling itself with n=2.
The useful thing about this is that if I then write another function like
function SubtractTwo = (n) =>
{
n - 2
}
PrintAndRepeat(SubtractTwo, 100)
it will count down like 100, 98, 96, 94. This can be very powerful when dealing with larger, more complex scenarios.
This might all seem a bit overcomplicated and difficult to follow but the important thing to remember is that functions can be treated the same as variables and passed around. If a function can be stored in a variable, used as an argument in another function and returned as a result from a function then you have functional programming. This can be very elegant and powerful for dealing with large complicated systems.
This type of programming involves programming small modules called actors that usually just have one simple job. These actors communicate by sending messages to other actors. These are all run by the hardware at the same time (concurrently). This type of programming is less common than the ones above; it is used extensively by communication systems like telephone and mobile switching stations. The reason I mention it here is because I believe that it will become more important in the future as we move towards hardware with more processing cores where concurrent programming is more powerful. Even if it doesn’t, knowing how to do this will pretty much guarantee you a well paying job at any telecommunications company.
A historical note: The original design of object oriented programming worked like this too, but the meaning of the term has changed over time.
There are a lot of advantages to writing code in this way. For example you can scale the size and speed of a program by simple adding more actors and more hardware, in a way that does not really have any limits. This is why it is needed for world wide data networks, because a lot of other software can’t scale as well. It also means you can switch out parts of the system and replace hardware or update code without taking the system offline.
I don’t know anything about quantum computer programming, except that it is totally different to normal programming. Probably none of the information in this article applies to it at all. Again I am mentioning it because I think it is likely to become more important in the future and learning to do it could be a valuable skill. If you want to know more there are quantum computer emulators that you can practice on and also at the current time IBM is offering free time on real quantum computers for developers to (remotely) run simple test software.
People often ask me ‘what is the best language to learn programming’. This is a bit like asking a mechanic ‘what is the best car to drive around in’. If they know you really well they might know all of your needs and desires and be able to recommend just the right one, but in most cases it depends on so many things that it is hard to answer this question.
Hopefully the sections on types and paradigms of programming gave you some idea of what interests you and what you are comfortable with. The next question is what do you want to do with it. If you want to write short scripts that make your life easier and perform simple tasks on your computer you will probably want an interpreter language. If you want to make games you should look at engines like Godot, Unity and Unreal and learn the languages they support (C# and C++ are your best bets here). You can make games in any language, these engines simply exist to make it easier and quicker to produce a finished game. If you are doing it for the love of programming you don’t need this. If you want to make a career of programming, you need to read up a lot on what languages are popular, and get a feel for which languages have a long-term future. Well actually you should probably just learn any old language you enjoy, as learning a second and a third programming language is usually easy once you have mastered your first, and knowing an unpopular language means fewer jobs but also less competition for them. If you want to do AI stuff like image recognition you should probably look at Python. Although there are a lot of other options, Python is quite a big player in this area and looks like it is not going anywhere. If you want to just tinker and learn, languages that are designed for ease of use are your best bet, the prime candidate for that in my opinion is Ruby, but Python is also recommended by many for this, and really most mainstream languages are roughly on par in terms of difficulty. If you want to become a functional programming purist you will probably want to try Haskell. There is one other language worth mentioning, merely because of the hushed tones and near mystical reverence with which it is referred to by a lot of programmers, and that is Lisp. I have been meaning to learn it myself but have never found the time. I don’t know much about it other than that it is quite different from other languages, and everyone who knows it talks about it as though it has religious significance for them. Also programmers that don’t know it don’t criticise it, which is rare as most programmers talk about languages as though they are the popular girls at high school criticising people’s fashion choices.
The things to take away when asking this question are:
1. This is not an irreversible decision, what you learn in one language will be useful in others and you can tinker around with multiple languages.
2. It matters what you want to do. Each language is a set of tools that will be better for some jobs than others.
3. It matters a lot which one you like, as your success in learning will depend on how interesting you find it. Try to read some code and get a feel for what you are comfortable with.
To finish off, here are a list of languages you can look up for further research, with some notes about how they fit into the larger picture. This list is not exhaustive, see this list for more. Note the Wikipedia list is ‘notable’ programming languages, meaning even that list is not complete. New languages are being created every day and some people create new languages as a hobby. These are the ones I know something about, and all of them are legitimate choices for learning programming.
AutoHotkey: Interpreted, imperative. This is only used for one thing, to make your computer press keyboard buttons and click and move the mouse for you. This is incredibly useful and everyone should learn it if they use windows. Not recommended for actual programs.
C: Compiled, imperative, low level (just one step up from assembly), fast, used for operating systems, robots, microcontrollers. Programmer has to manage memory.
C++: Compiled, functional, object oriented, fast, programmer has to manage memory. Popular. Used for virtually every type of software, dominates games and operating systems.
C#: Compiled - just in time, functional, object oriented. Popular. (dotnet)
Clojure: Compiled, concurrent, functional. A type of Lisp. (Java – JavaScript and dotnet versions also exist)
Erlang: Compiled - virtual machine, concurrent. This is the language the telecommunication companies use.
F#: Compiled - just in time. C# with a stronger focus on functional programming. (dotnet)
Go: Compiled, concurrent, object oriented. Search for golang as go is a terrible name for web searches.
Haxe: Transpiled, object oriented. Haxe is transpiled, which means it is designed to be compiled into other languages. It supports transpiling into most of the popular languages on this list. This makes it a kind of Swiss-army knife that in theory can be used for any job. In practice however the transpiled code is often difficult to work with.
Java: Compiled – virtual machine, object oriented, functional. Java is the core language of the Java ecosystem which includes a lot of other languages which all compile to run on the same virtual machine. Popular. (Java)
JavaScript: Interpreted, object oriented, functional. Very popular. JavaScript is not part of the Java ecosystem and has nothing to do with Java. It is the core language in its own ecosystem. JavaScript is used almost exclusively for websites and web applications and runs in browsers. The JavaScript ecosystem dominates the web. No static type system. I recommend learning TypeScript instead of this. (JavaScript)
Kotlin: Compiled, object oriented, functional. Designed by the people who make the best IDE’s, so you can bet on good IDE support. (Java) (JavaScript)
Lisp: Interpreted, functional. Original Lisp is not used much any more, try its descendants: Common Lisp, Scheme, Racket or Clojure.
Lua: Interpreted, object oriented, functional. Simple syntax, often recommended for beginners. No static type system.
PHP: Interpreted, functional, object oriented, Popular. PHP is mostly used for web servers, which is what it was originally designed for. It used to completely dominate that niche but it is now losing ground as you can run a web server with pretty much any language.
Python: Interpreted, object oriented, functional. Popular, probably the most popular interpreter language. Python is loved by mathematicians because it has very well thought out data structures. Often recommended for beginners.
Ruby: Interpreted, object oriented, functional. One of the most beginner friendly languages, designed with ease of use as the primary goal above all others.
Rust: Compiled, functional, concurrent, fast. Rust was designed to be a successor to C++ where memory management is much easier because it is controlled by a memory safety system that enforces good memory management in the same way that static type systems enforce good data type management.
Typescript: Interpreted, object oriented, functional. Very popular. Typescript is the statically typed version of JavaScript. Can be used everywhere JavaScript can. (JavaScript)
The names in brackets on some of these are the name of the ecosystem they belong to. Languages within the same ecosystem can interact with each other in a relatively seamless way and share libraries. This means if you learn one of them you can step across to the others relatively easily.
Popular means they are often featured in the top 5 most widely used languages (a list which changes over time and depending on who you ask).