Programming Languages & IDEs
Computers ultimately understand only one thing: patterns of binary 1s and 0s. Yet almost nobody writes programs directly in binary — it would be painfully slow and terribly easy to get wrong. Instead, programmers pick a language that suits the job and rely on other software to turn their code into something the processor can actually run. This lesson looks at the different levels of programming language, the translators that convert your code, and the toolkit that makes writing software far quicker.
High-level and low-level languages
Programming languages sit on a scale, depending on how close they are to human language or to the raw instructions of the processor. A high-level language such as Python, Java or C++ is written using English-like keywords such as ‘if’, ‘print’ and ‘while’. A single line of high-level code usually stands in for many processor instructions. This makes high-level code easier to read, write and debug, and it is portable — the same program can run on different types of computer once it has been translated. Its one catch is that it must always be translated before the processor can understand it.
A low-level language is much closer to the hardware. The lowest level is machine code — pure binary that the processor runs directly, with no translation needed. Assembly language is also low-level, replacing binary with short memory-joggers called mnemonics. Low-level code is hard for people to read and write, and it is machine-specific, so it only works on one type of processor. In return it runs very fast, uses little memory and gives the programmer precise control over the hardware, which is why it is used for tasks like device drivers and other software that must squeeze the most out of the machine.
High-level languages use English-like keywords, are easy to read and debug, and are portable across different machines. Low-level languages are close to the hardware: harder to write and machine-specific, but faster and more memory-efficient.
Because one high-level statement replaces many machine-code instructions, programmers can build software much faster and with fewer mistakes. A program written once in a high-level language can also be translated to run on many different computers, whereas low-level code usually has to be rewritten for each new type of processor. For most everyday software, that productivity and portability easily outweigh the small loss of speed.
Translators: compilers and interpreters
Because a processor can only run machine code, any program written in a high-level language has to be converted first. A translator is a program that turns source code — the code a programmer writes — into machine code. The two translators you need to know are the compiler and the interpreter. They do the same job in very different ways.
A compiler translates the entire program in one go, before it is run. It produces a separate executable file of machine code that can then be run on its own, without the source code or the compiler being present. Compiling a large program can take a while, but the finished executable then runs quickly. A compiler checks the whole program and produces an error report at the end, listing the mistakes together rather than stopping at the first one.
An interpreter translates and runs the program one statement at a time. It does not create an executable file, so the interpreter and the source code are both needed every time the program runs. Because it translates as it goes, an interpreted program runs more slowly. However, the interpreter stops at the very first error it meets and reports it straight away, which makes mistakes much easier to find and fix while a program is still being developed.
A compiler translates the whole program at once into a fast, standalone executable, but reports all its errors together at the end. An interpreter translates line by line, runs more slowly and needs the source code each time, but stops at the first error, making debugging easier.
A compiler is a good choice for finished software you want to share. The executable runs fast, works without the original source code, and keeps that source code hidden from users. The drawbacks are that you must recompile the whole program after every change, and the executable only runs on the type of processor it was built for.
An interpreter suits writing and testing programs. Errors are caught one at a time, and the same source code will run on any device that has the right interpreter, which makes it very portable. The trade-offs are slower running speed and the fact that the source code must be handed over to anyone who wants to run the program.
Integrated Development Environments
Writing, running and fixing code in separate programs would be slow, so programmers use an Integrated Development Environment, or IDE — a single application that brings all the tools they need into one place. Popular examples include IDLE for Python, PyCharm and Visual Studio. An IDE usually provides four kinds of tool.
- Editor — where you type your code. Helpful features such as colour-coded keywords (syntax highlighting), automatic indentation, auto-complete and line numbering make code faster to write and easier to read.
- Error diagnostics — tools that help track down mistakes. A breakpoint pauses the program at a chosen line, and the programmer can then step through the code line by line and watch how the values stored in variables change, pinpointing where a fault happens.
- Run-time environment — a run-time environment lets the programmer run the program from inside the IDE and see its output straight away.
- Translator — a built-in compiler or interpreter that converts the code into machine code so it can actually run.
Because all of these tools sit in one window, an IDE speeds up the whole write, run and debug cycle. That is why almost all software today is created using one.