Imperative programming is the oldest and most direct paradigm: you tell the computer how to do something as an ordered sequence of statements that change state — assign a value, loop, increment a counter, branch on a condition.1
Core ideas
The defining trait of imperative code is mutable state: variables change over time, and the order of statements matters. This mirrors how the hardware actually works — the CPU executes one instruction after another, updating registers and memory — which is why it feels natural and why early languages were imperative. That same power is the risk: many subtle bugs come from state changing when or where you did not expect.
Procedural programming
Procedural programming is imperative code organised into reusable procedures (functions). Instead of one long script, you factor work into named routines that call each other.1 C is the classic procedural language, and Fortran and COBOL are early examples. Procedural style pairs naturally with manual memory management and tight performance loops.
When it fits
Reach for imperative or procedural style when you are close to the hardware or in a tight performance loop, where you want exact control over each operation. Go is mostly procedural with lightweight interfaces. It contrasts with declarative programming, which describes what you want rather than how, and with functional programming, which avoids mutable state altogether. Most languages are multi-paradigm, so an imperative inner loop often sits inside object-oriented or functional code.1
Sources
-
Imperative programming — Wikipedia, for the definition, the role of mutable state and ordered execution, and the procedural sub-style. ↩ ↩2 ↩3