/ janturon.cz / Od kodéra k analytikovi / Programovací paradigmata

Programovací paradigmata

Algoritmus je posloupnost kroků mající svůj vstup a výstup. Počátky smysluplného programování zavádí ale až metoda rozděl a panuj, která složitý problém (program) rozdělí na podprogramy. Těm se v sedmdesátých letech začalo říkat procedury a jazyky je podporující (Pascal, C) jako procedurální neboli strukturované.

Při nárůstu složitosti algoritmů se tímto přístupem začaly projevovat dva nedostatky: kolize jmen a GRASP. To bylo vyřešeno jmennými prostory a objekty: jazyky tyto rysy podporující se nazývají objektové. Absence zásad GRASP vede k antivzoru anemickému doménovénovému modelu - pracování s objekty procedurálním stylem.

Společnou vlastností těchto imperativních jazyků je stav programu, který je změněn provedením příkazu. Alternativou k tomu je deklarativní přístup: místo posloupnosti příkazů problém popíšeme jazykovým konstruktem (relací) a jeho vykonání necháme na překladači. Cena za toto intuitivní a stručné vyjádření je ztráta kontroly nad postupem, jakým je problém řešen. Mezi speciální deklarativní přístupy patří:

programovací jazyky

Každý přístup (paradigma) je vhodné pro řešení jiné třídy problémů. Například s daty uchovávané v relacích (tabulkách) se špatně pracuje objektově (ORM nástroje mají mnoho omezení). Některé moderní jazyky jsou proto multiparadigmatické: v jazyce C# lambda funkce umožňují funkcionální paradigma, LINQ pak dotazovací; v jazyce SQL jsou uložené procedury zapisovány imperativním paradigmatem). Výhoda použití jiného paradigmatu je zejména v:

Všechna paradigmata mají teoreticky stejnou vyjadřovací mohutnost, ale faktem je, že většina velkých programů je psána objektově. Je proto nejperspektivnější začít objektovým programováním a občas (pokud je to vhodné) to doplnit jiným paradigmatem.

Ukázky algoritmu počítající faktoriál vyjádřené v různých jazycích a paradigmatech:

C (procedurální)

#include "stdio.h" // podprogram int factorial(int n) { if(n<1) return 1; return n * factorial(n-1); } // program void main() { printf("%d",factorial(5)); }

C++ (objektové)

#include <iostream> // třída - deklarace class fact { int state; public: fact(int n) : state(n) { } int evaluate(); }; // třída - definice int fact::evaluate { if(state<1) return 1; fact* sub = new fact(state-1); int result = this->state * sub->evaluate(); delete sub; return result; } // program int main() { fact f5(5); std::cout << f5.evaluate(); return 0; }

Haskell (funkcionální)

-- výchozí bod fac 0 = 1 -- matematická indukce fac (n+1) = (n+1) * fac n // program fac 5

Viz též zde.

Prolog (logické)

% první pravidlo factorial(0,1). % druhé pravidlo factorial(N,X) :- N>0, N1 is N-1, factorial(N1,X1), X is N * X1. % program ?- factorial(5,F5). % výstup po spuštění F5=120

SQL (procedurální)

-- procedura DROP PROCEDURE IF EXISTS factorial; DELIMITER // CREATE PROCEDURE factorial(IN n TINYINT, OUT ret BIGINT) BEGIN SET max_sp_recursion_depth=100; IF n < 1 THEN SELECT 1 INTO ret; ELSE CALL factorial(n-1, ret); SELECT n * ret INTO ret; END IF; END// DELIMITER ; -- program CALL factorial(5,@fac5); SELECT @fac5;