-
The Procedural Paradigm follows the Imperative Paradigm but organizes code into procedures (or functions).
Purely Procedural Languages
-
Today, there is almost nothing “purely procedural.”
-
Fortran :
-
Although it evolved over time and gained modern features, the original Fortran was strictly procedural, focusing on functions that manipulated data.
-
-
Algol :
-
One of the first languages to adopt a purely procedural style.
-
Concept of "objects" in the Procedural Paradigm
-
Talking about "procedural implementation for objects" creates a contradiction , since objects imply an object-oriented paradigm (encapsulation, inheritance, polymorphism, etc.).
-
Procedural programming focuses on organizing code around functions that operate on data.
-
Code is organized into functions (or procedures) and control flow, without object-oriented abstractions like classes or inheritance.
Applying the Procedural Paradigm
In C
-
C was designed to be procedural , meaning it relies on functions and procedures (or subroutines) to manipulate data and control execution flow. C code is organized around functions operating on variables and data structures, with flow controlled by loops (
for,while), conditionals (if,else), and function calls. -
However, C is not purely procedural for several reasons:
-
Use of data structures :
-
C allows
structs to group data, resembling encapsulation, often seen in OOP.
-
-
Macros and preprocessing :
-
The preprocessor (
#define, directives) allows abstraction beyond purely procedural limits.
-
-
Pointers and memory manipulation :
-
Direct memory manipulation provides abstraction capabilities similar to some OOP patterns.
-
-
-
Examples :
-
Procedural :
#include <stdio.h> int somar(int a, int b) { return a + b; } int main() { int x = 5; int y = 10; int resultado = somar(x, y); printf("Resultado da soma: %d\n", resultado); return 0; }-
"OOP" :
#include <stdio.h> typedef struct { char rua[100]; char cidade[50]; char estado[50]; } Endereco; typedef struct { char nome[50]; int idade; Endereco endereco; } Pessoa; void imprimir_endereco(const Endereco *e) { printf("Endereço: %s, %s, %s\n", e->rua, e->cidade, e->estado); } void imprimir_pessoa(const Pessoa *p) { printf("Nome: %s, Idade: %d\n", p->nome, p->idade); imprimir_endereco(&p->endereco); } int main() { Pessoa p = {"João", 30, {"Rua das Flores", "São Paulo", "SP"}}; imprimir_pessoa(&p); return 0; }#include <stdio.h> typedef struct { char nome[50]; int idade; } Pessoa; void saudar(Pessoa *p) { printf("Olá, meu nome é %s e tenho %d anos.\n", p->nome, p->idade); } typedef struct { Pessoa pessoa; char matricula[20]; } Estudante; void saudar_estudante(Estudante *e) { saudar(&e->pessoa); printf("Minha matrícula é: %s\n", e->matricula); } int main() { Estudante e = {{"João", 20}, "12345"}; saudar_estudante(&e); return 0; }
-
In Rust
-
Rust is a hybrid language .
-
It allows procedural code (functions, data manipulation) but also supports structs and traits, enabling OOP-like abstraction without classical inheritance or polymorphism.
-
Creating "objects" in Rust (
struct+impl) is hybrid: procedural logic with object-like composition. -
Objects in Rust :
-
Structs with methods are not true OOP objects; they use data and function composition .
-
-
Examples :
-
Hybrid: Procedural + "OOP" :
struct Carro { modelo: String, ano: i32, } impl Carro { fn novo(modelo: &str, ano: i32) -> Carro { Carro { modelo: modelo.to_string(), ano, } } fn detalhes(&self) { println!("Modelo: {}, Ano: {}", self.modelo, self.ano); } } fn main() { let carro1 = Carro::novo("Fusca", 1985); carro1.detalhes(); }-
Procedural :
fn maior(a: i32, b: i32) -> i32 { if a > b { a } else { b } } fn main() { let resultado = maior(10, 20); println!("O maior número é: {}", resultado); }struct Ponto { x: i32, y: i32 } fn distancia(p1: &Ponto, p2: &Ponto) -> f64 { let dx = p2.x - p1.x; let dy = p2.y - p1.y; ((dx * dx + dy * dy) as f64).sqrt() } fn main() { let p1 = Ponto { x: 3, y: 4 }; let p2 = Ponto { x: 7, y: 1 }; println!("Distância: {}", distancia(&p1, &p2)); }
-
In Zig
-
Zig is fundamentally procedural .
-
It lacks native OOP features like classes, inheritance, or polymorphism.
-
Structs :
-
No inheritance. Uses composition instead.
-
No constructors/destructors; manual init functions handle resource setup.
const std = @import("std"); const Pessoa = struct { nome: []const u8, idade: u32, pub fn init(nome: []const u8, idade: u32) Pessoa { return Pessoa{ .nome = nome, .idade = idade }; }, pub fn saudar(self: *Pessoa) void { std.debug.print("Olá, meu nome é {} e tenho {} anos.\n", .{ self.nome, self.idade }); }, }; pub fn main() void { var pessoa = Pessoa.init("João", 30); pessoa.saudar(); }
-
-
Examples :
-
Procedural :
const std = @import("std"); fn somar(a: i32, b: i32) i32 { return a + b; } pub fn main() void { const resultado = somar(10, 20); std.debug.print("A soma é: {}\n", .{resultado}); } -
"OOP" :
const std = @import("std"); const Falar = struct { falar: fn() void }; const Cachorro = struct { falar: Falar, nome: []const u8 }; const Gato = struct { falar: Falar, nome: []const u8 }; fn falar_cachorro() void { std.debug.print("Au Au!\n", .{}); } fn falar_gato() void { std.debug.print("Miau!\n", .{}); } pub fn main() void { var cachorro = Cachorro{ .falar = Falar{ .falar = falar_cachorro }, .nome = "Rex" }; var gato = Gato{ .falar = Falar{ .falar = falar_gato }, .nome = "Whiskers" }; cachorro.falar.falar(); gato.falar.falar(); }
-
In Go
-
Go is strongly procedural with optional abstraction through interfaces.
-
No classes, inheritance, or traditional polymorphism.
-
Examples :
-
Procedural :
package main import "fmt" func somar(a, b int) int { return a + b } func main() { fmt.Println("Resultado:", somar(10, 20)) } -
"OOP" :
package main import "fmt" type Saudável interface { Saudar() } type Pessoa struct { Nome string; Idade int } func (p *Pessoa) Saudar() { fmt.Println("Olá,", p.Nome) } type Animal struct { Nome string } func (a *Animal) Saudar() { fmt.Println("Roar! Eu sou", a.Nome) } func main() { var s Saudável pessoa := &Pessoa{"João", 30} animal := &Animal{"Leão"} s = pessoa; s.Saudar() s = animal; s.Saudar() }
-
In Lua
-
Lua can be used procedurally but can simulate OOP via tables + metatables .
-
Examples :
-
Procedural :
function somar(a, b) return a + b end print("Resultado: " .. somar(5, 10)) -
"Simulated OOP" :
Pessoa = {}; Pessoa.__index = Pessoa function Pessoa:new(nome, idade) local self = setmetatable({}, Pessoa) self.nome, self.idade = nome, idade return self end function Pessoa:saudar() print("Olá, meu nome é " .. self.nome .. " e tenho " .. self.idade .. " anos.") end Aluno = setmetatable({}, Pessoa) Aluno.__index = Aluno function Aluno:new(nome, idade, matricula) local self = setmetatable(Pessoa:new(nome, idade), Aluno) self.matricula = matricula return self end function Aluno:saudar() print("Sou aluno " .. self.nome .. " e minha matrícula é " .. self.matricula) end local pessoa1 = Pessoa:new("João", 30) local aluno1 = Aluno:new("Maria", 20, "12345") pessoa1:saudar() aluno1:saudar()
-