What Is Programming?
What a program is, how programming languages differ, and how source code becomes something a processor can run.
What a program is
A program is a set of instructions that tells a computer exactly what to do, step by step, together with the data those instructions work on. A recipe is a useful comparison: it lists ingredients (the data) and steps (the instructions). The difference is that a computer follows the steps literally. It never guesses what you meant, so every step has to be precise and complete.
Programming is the work of turning a task into such instructions: understanding the problem, designing the steps (an algorithm), writing them down in a programming language, and testing that the result does what it should. Typing the code is often the smallest part of the job.
Almost every program follows the same basic pattern:
- Input — it receives data: from a keyboard, a file, a network connection or a sensor.
- Processing — it calculates, compares, sorts or changes that data.
- Output — it shows, saves or sends the result.
What a programming language is
A programming language is a formal language with strict rules for writing instructions that a computer can carry out. "Formal" means that its grammar and meaning are precisely defined, so a statement cannot be read two ways the way English can: "I saw the man with the telescope" can mean two things.
What you write in a programming language is called source code: plain text that people can read and edit. Every language defines its keywords, its punctuation and the rules for combining them (its syntax), and what each valid statement does when it runs (its semantics).
Machine code and assembly
A processor (CPU) understands only one language: machine code, instructions encoded as binary numbers. Each instruction is a small, simple operation — copy a value into a register, add two values, jump to another instruction if a value is zero. Every processor family has its own set of instructions, its instruction set: machine code for an Intel or AMD PC (x86-64) does not run on the ARM processor in a phone or a Raspberry Pi.
Machine code is almost impossible for people to read. That is why
assembly language exists:
it gives each machine instruction a short, readable name (a
mnemonic) such as mov or add. A
tool called an assembler translates it one-to-one into
machine code. Here are two x86-64 instructions that put 2 in a
register and add 3 to it, with the machine code bytes (in
hexadecimal) that the assembler produces:
; x86-64 assembly machine code (hex) mov eax, 2 ; eax = 2 B8 02 00 00 00 add eax, 3 ; eax = eax + 3 83 C0 03
Even this tiny calculation needs you to know which registers exist and how the processor works. Assembly is still used where every instruction counts — parts of operating systems, device drivers, tiny microcontrollers — and for analyzing malware, but almost nobody writes whole applications in it.
High-level and low-level languages
Languages are placed on a scale by how close they are to the hardware.
- A low-level language is close to the processor: machine code and assembly. You control every detail, but the code is long, hard to read and tied to one processor family.
- A high-level language hides the hardware behind abstractions such as variables, functions, loops and text strings. Python, Java, C# and JavaScript are high-level. One line of such a language often becomes dozens of machine instructions, and the same code can run on different processors.
The scale is relative. C is high-level compared with assembly, but is often called "low-level" compared with Python, because it lets you work directly with memory addresses and leaves memory management to you (see Memory Management).
From source code to a running program
Source code in a high-level language has to be translated into machine code before a processor can run it. There are three common strategies, and they differ in when the translation happens.
Compiled languages
A compiler translates the whole program in advance into a
machine-code file, an executable (such as an
.exe on Windows). You then run that file; the compiler
and the source code are no longer needed. C, C++, Go and Rust work
this way. Compiled programs start fast and run fast, and the
compiler catches many mistakes before the program ever runs. The
downside: you have to compile again after every change, and
separately for each kind of processor and operating system.
Interpreted languages
An interpreter reads the source code and carries it out while the program runs, without producing a separate executable. The same source file runs on any machine that has the interpreter, and you can change a line and run it again immediately. The price is speed, because translation work happens during every run, and some mistakes only show up when the faulty line is reached. Python, Ruby, PHP, Bash and PowerShell are usually interpreted. How Python does this internally, with bytecode, is explained in What Is Python?.
Just-in-time compilation
Just-in-time (JIT) compilation combines both approaches. The program starts out interpreted (or as bytecode), and while it runs, the runtime compiles the parts that are used most often into machine code. Java and the JavaScript engines in web browsers work this way, and so does PyPy, an alternative Python implementation; C#'s runtime compiles each method the first time it runs. JIT gives nearly the speed of compiled code while keeping the flexibility of distributing one file for every platform.
Categories of languages
CompTIA's entry-level IT exams — Tech+ and its predecessor, IT Fundamentals+ (ITF+) — sort languages into a few categories by what they are used for and how they run.
| Category | What it is for | Examples |
|---|---|---|
| Compiled programming language | Applications, operating systems, games, anything that must be fast | C, C++, Go, Rust |
| Interpreted / scripting language | Automating tasks, gluing programs together, web pages | Python, JavaScript, PowerShell, Bash, Windows batch |
| Query language | Asking a database for data, or changing it | SQL |
| Assembly language | Direct control of the processor | x86-64 assembly, ARM assembly |
| Markup language | Describing the structure of a document or data | HTML, XML, Markdown |
Scripting languages
A scripting language is an interpreted language used mainly to automate tasks and to control other programs: renaming a thousand files, creating user accounts, running a backup every night. Scripts are usually short and run directly from their source file. The line with "general-purpose" languages is blurry — Python is both a scripting language and a language for large applications, and JavaScript started as a way to script web pages.
Query languages
A query language is a language for retrieving and changing data in a database. The most important one is SQL (Structured Query Language). SQL is declarative: you describe which data you want, and the database decides how to find it.
SELECT name, price FROM products WHERE price < 10 ORDER BY price;
Markup languages
A markup language adds tags to text to describe its structure or meaning: this is a heading, this is a paragraph, this is a link. HTML (for web pages) and XML (for data) are markup languages.
<h1>Opening hours</h1> <p>Monday to Friday, <strong>9:00 to 17:00</strong>.</p>
HTML is not a programming language. It cannot calculate, make decisions or repeat steps: there is no way to say "if the shop is closed, show a different message" in HTML alone. It only describes what a document contains. On a web page, that logic is added by a real programming language — JavaScript in the browser, or a language such as PHP or Python on the server.
One program in three languages
The same small program — add three prices and print the total — looks quite different in three popular languages. All three print exactly the same line.
In Python (interpreted):
prices = [2.50, 1.25, 3.75]
total = sum(prices)
print(f"Total: {total:.2f}")
Total: 7.50
In JavaScript (JIT-compiled by the engine):
const prices = [2.50, 1.25, 3.75];
const total = prices.reduce((sum, price) => sum + price, 0);
console.log(`Total: ${total.toFixed(2)}`);
Total: 7.50
In C (compiled):
#include <stdio.h>
int main(void) {
double prices[] = {2.50, 1.25, 3.75};
double total = 0.0;
for (int i = 0; i < 3; i++) {
total += prices[i];
}
printf("Total: %.2f\n", total);
return 0;
}
Total: 7.50
A few differences stand out:
-
C needs more ceremony: an
#includefor the printing functions, amainfunction where the program starts, and an explicit type (double,int) for every variable. - C marks the end of each statement with a semicolon and groups statements with curly braces. JavaScript does the same; Python uses line breaks and indentation instead.
-
Python and JavaScript have ready-made ways to add up a list
(
sum,reduce); in C you write the loop yourself. -
The C version has to be compiled (for example with
gcc total.c -o total) before it can run; the Python and JavaScript versions run straight from the source file.
Choosing a language
There is no best language, only a better fit for a task. The questions that usually decide it:
- Where must it run? Code inside a web browser is JavaScript; an iPhone app is usually Swift; a microcontroller often needs C.
- How fast must it be? Games, databases and operating systems use compiled languages such as C, C++ or Rust. For most scripts and business applications, the speed of an interpreted language is more than enough.
- What already exists? Libraries, frameworks and existing code often decide it: data analysis and AI are strongly tied to Python, many enterprise systems to Java or C#.
- Who will maintain it? A language the team already knows is usually a better choice than a slightly better one nobody knows.