
A programozási paradigmák, a szoftverfejlesztés misztikus tanai közé tartoznak. Akár a mágia különböző formái, ezek is más-más megközelítéseit jelentik a számítógépek kódolásának. Bár elég jól dokumentált, komoly irodalommal bíró fogalmakról van szó, pontos definíciókról mégsem beszélhetünk, ahogy teljes elkülönülésük, vagy precíz hierarchiába való rendezésük is álom csupán. Mégis, ahogy a fantázia-világok mágusai, úgy a programozóból mérnökké váló tanoncok sem kerülhetik meg a programnyelvek mögött megbúvó, már-már a filozófia, de legalábbis a matematika húrjait pengető különböző aspektusok tanulmányozását. Lehet ugyan valaki élelmes tűzvarázsló webfejlesztő, mindenre elszánt boszorkánymester rendszergazda, vagy netán etikus paplovag hacker, csak a mélyebb tanok megértésével válhat valaki teljes értékű játékossá, esetleg mesterré a szoftverfejlesztésben.

Egy-egy programnyelv fontos attribútuma, hogy mely paradigmát, vagy paradigmákat támogatja. Akadnak nyelvek, amelyek eszköztára többől is válogat, a programozóra bízva ezek vegyítését, míg mások egy bizonyos koncepció köré szerveződve rákényszerítik használójukat az alkotóik által kívánatosnak tartott útra. Ez nem feltétlenül rossz dolog. Egy-egy problémakör más-más hozzáállást követelhet meg a hatékony és elegáns megoldás megtalálásához, bizonyos minták követése pedig sok sikertelenségtől kímélhet meg minket. A programozási paradigmák minél szélesebb körű ismerete elengedhetetlen fegyvertény a szoftverfejlesztésben, tanulmányozásuk pedig látókörtágító és szórakoztató is egyben. A teljesség igénye nélkül, és ingoványos talajon kelve át ugyan, de összegyűjtöttem párat. A kiegészítéseket, kommenteket, építő kritikát, mint mindig, most is örömmel veszem!
Objektum-orientált programozás

Bár az elgondolás már az az 1967-es Simula nyelvben is fellelhető volt, majd később a Smalltalk nyelvben teljesedett ki, de az objektum-orientált paradigma a 90-es évektől vált igazán elterjedtté, sőt valósággal meghatározta a korszakot. A könyvespolcok az objektumorientált programozás rejtelmeit firtató művekkel voltak tele, élükön a szoftver-tervezésben alapműveltségnek számító, újító szellemű kiadvánnyal, a Gang of Four szerzőcsapat által jegyzett, Programtervezési Minták c. könyvvel. Boldog-boldogtalan a Delphi és persze a C++ rejtelmeibe ásta bele magát ekkor, és a lelkesedés a mai napig tart: a legtöbb ma is használt nyelv, mint pl. a Java, a PHP, a C#, a már említett C++, vagy a Python, a Ruby illetve a JavaScript is magáévá tette ezt a látásmódot.
Az objektum-orientált programozásnak (röviden: OOP) több sarokköve is van. Először is nélkülözhetetlen, az adatok és a rajtuk elvégzett műveletek egységbe zárása. Például egy pont kirajzolásához szükséges koordináta, valamint a pontot ez alapján megjelenítő utasítássor nem csak úgy lebegnek a program összes többi alkatrészével egy térben, hanem elkülönülve megalkotnak egy pont-objektumot, mely magában foglalja mindezeket. A szélesebb értelemben vett rendszer pedig efféle objektumok interakciójaként fogható fel. Akár csak a valóságban, már ha a „pont” és a „vonal” fizikai létezők, nem pedig a matematikus kivetítései lennének csupán...
Az objektumok újabb objektumok építőkockáivá is válhatnak az öröklődés által, ami szintén egy fontos eleme a megközelítésnek. Az öröklődés segítségével az objektumok újrahasznosíthatják egymás jellemzőit. Ha van például egy generális, Humanoid
névre hallgató objektumunk, akkor egy specializáltabb eset, mint például a Hobbit
megörökölheti a Humanoidot megvalósító kódot, kiegészítheti vagy módosíthatja azt a saját igényei szerint. (Mondjuk a "két láb"
tartalmú változót, "két szőrös talp"
-ra cserélheti, a sétálást megvalósító kód mellé pedig egy sör-tánc metódust is iktathat.)
A történet persze nem ér véget itt, a látásmód ereje pedig könnyen belátható: az elvont problémákat a mindennapi életben megszokott módon modellezve könnyebbé teszi az azokról való gondolkodást. Ha egy egyszerűbb játék megírásához szükséges kismillió, a számítógéppel elvégeztetendő feladatra gondolunk, talán egyből el is megy a kedvünk az egésztől, ám ha objektumokra bontva közelítjük meg a problémát, máris átláthatóvá, és részenként megoldhatóvá tehetjük azt. Strukturálja tehát a gondolkodásunkat és a kódunkat is, nagyban megkönnyítve ezáltal a fejlesztést.
Kétélű fegyverről beszélünk azonban, túlzásba víve hajlamosak lehetünk túl sokféle objektum és túl összetett hierarchia létrehozására, megfeledkezve az egyéb paradigmák nyújtotta lehetőségekről. Ilyenkor az objektumok nyújtotta hatalom könnyen a mestere ellen fordulhat.

Funkcionális programozás

A funkcionális programozás ínyenceknek való tudomány. MÁGUS-os hasonlattal élve, ha az OOP a varázshasználókat jelenti, akkor a funkcionális programozás minden bizonnyal a harcművész kasztnak feleltethető meg. Míg az OOP-t alkalmazó fejlesztő nagy gonddal szövögeti az objektum-hierarchia hálóját, addig a funkcionális programozó a Pszí Lambda összpontosításával, villámgyorsan és egyenes úton jut el a célba.
Alapvetően matematikai megközelítésről lévén szó, ez az aspektus komoly elméleti megalapozottsággal bírt már a számítástechnika fejlődésének korai szakaszában is. A funkcionális paradigma nem az adatok és a műveletek egységbe zárásáról és a kézzelfogható világ dolgaihoz hasonló absztrakciókról szól, helyette a programot az adatokon végzett transzformációk sorozataként fogja fel. A funkcionálisan megírt szoftver tehát sokkal inkább folyamat, mint rendszer.
Ezeket a transzformációkat függvényekként jellemezhetjük, amelyek az adott bemeneti paraméterek kimeneti paraméterekké való alakítását írják le. Fontos jellemzője a megközelítésnek hogy az adatok megváltoztathatatlanok, új értékek generálódnak minden műveletnél, a régiek pedig nem íródnak fölül. Tisztán funkcionálisan gondolkodva az egyes függvényeken kívüli térben nincsenek egyéb, globális értéktárolók, amiket a függvények lekérdezhetnek vagy beállíthatnának – ellentétben az objektumorientált modellel, ahol az objektumok szabadon hozzáférhetnek a globális térhez, valamint egymás belső adatait is módosíthatják. A függvények egymással csupán bemeneti és kimeneti szinten kommunikálnak, a program futása nem függ valamilyen külső állapottól, adott paraméterekkel, mindig ugyanazokat az értékeket produkálja. Funkcionális nyelven úgy mondjuk, nincsenek mellékhatások, valamint a program állapot nélküli és tiszta.

Ez a tiszta működés teszi olyan kívánatossá a funkcionális programozást, ugyanis az így írt programok könnyen átláthatók, tesztelhetők, megbízhatóbb kód készítésére ösztönzik a fejlesztőt. Az egyéb külső állapotoktól való függetlenség miatt kifejezetten alkalmasak az olyan párhuzamos/konkurens/elosztott rendszerek kivitelezésére, mint a hálózati kommunikációt igénylő alkalmazások, vagy a több processzormagot kihasználó szoftverek. Nem csoda, hogy napjainkban komoly reneszánszát éli ez a megközelítés, valamint, hogy a legtöbb modern nyelv az objektumorientált mellett funkcionális lehetőségeket is támogat. Fontosabb funkcionális, vagy jelentős részben funkcionális programnyelvek például a Haskell, az Erlang, a Lisp-nyelvek, az F# vagy a Scala.
Logikai programozás

A logikai programozás a szokványos programozási mintáktól merőben eltérő megközelítés. A funkcionális paradigmával ugyan rokonítható (mindketten a Nagy Lambda gyermekei), de míg fivére a funkciók fegyverével vágja át a gordiuszi csomót, addig emez a puszta logika segítségével csap le, vagy inkább következtet ki. Az adatok ekkor, mint tények, állítások és a rájuk vonatkozó szabályok vannak jelen.
A programozónak nincs más dolga, mint definiálni egy ilyen logikai rendszert, ezek után pedig kérdéseket szegezni neki. Ha tudjuk például, hogy Tyrion egy Lannister, valamint hogy a Lannisterek mindig megfizetik az adósságukat, akkor a rendszer könnyedén ki tudja következtetni a tényt, hogy Tyrion sosem marad adós.

A logikai programnyelvek, mint pl. a Prolog, az ASP, vagy a Datalog ennél jóval összetettebb problémák megoldására is képesek. A fentiekből (és még néhány ezer tényből és szabályszerűségből) talán már kikövetkeztethető, hogy a mesterséges intelligencia kutatásban, azon belül is első sorban az úgynevezett szakértői rendszerek kifejlesztésében jutott elévülhetetlen szerep ennek a paradigmának.
Egy széleskörű ismereteket tartalmazó adatbázis felállításával a logikai következtetés igen ütőképes lehet. Orvosi vagy technikai diagnosztika, természeti erőforrások felkutatása, sőt bűntények megoldása is a lehetséges alkalmazási területek közé esik. Nyelvi rendszerekkel való kísérletezésre éppúgy alkalmas, mint adatbázisokkal való munkára. Deklaratív volta, lekérdezés alapú működése olyan elterjedt programnyelvekre is hatást gyakorolt, mint például az SQL, mely a világinternet jelentős részének adatbázis igényeit elégíti ki, köztük vélhetően ezen blogét is.
Metaprogramozás

A metaprogramozás fantasztikus elemek nélkül is könnyen beindíthatja képzeletünket, hiszen voltaképpen a program azon képességéről beszélünk, hogy az megváltoztathassa saját kódját. Élő szövet a belső fémvázon, vagy legalábbis majdnem. Többféle módszer is létezik ennek elérésére. Jellemzően az adott nyelv a saját programkódját is, mint adatot képes kezelni, így aztán a programon belülről tudjuk manipulálni és futtatni annak részeit. Ez azon kívül, hogy sok izgalmas, filozófiai és művészeti lehetőség előtt tárja szélesre a kaput, szakavatott kézben villámgyors eszközt is jelent bizonyos problémák megoldására. Bár a program jó eséllyel válik nehezebben értelmezhetővé, magának a nyelvnek új funkciókkal való kiegészítése, vagy a program kódjának futás közben történő megváltoztatása könnyen lerövidítheti a megoldása felé vezető utat.

Jól érzékelteti továbbá a metaprogramozás jelentőségét, hogy legkorábbi megvalósítása Lisp nyelven történt. Ez a lassan 60 évessé váló, a mai napig is nehezen megkerülhető, sok más nyelv tervezésére is hatást gyakorló programnyelv többek között a mesterséges intelligencia kutatások fontos eszköze.
A metaprogramozás különböző formái több nyelvben is megtalálhatóak, a funkcionális Erlang, a Haskell, az OCaml vagy a Lisp különböző változatai (Scheme, Common Lisp, Clojure) illetve az objektum-orientált paradigmát teljes mértékben támogató Ruby is jó kiindulási pont lehet. Sőt a logikai Prolog is támogatja a tudás-bázis futásidejű módosítását, ami szintén a metaprogramozás egy formája.
Nem is az informatika tudományának óceánjába, a víz fölött áramló levegőbe pacskoltunk csupán csak bele a fentiek által. Jó lett volna még beszélni a programozási paradigmák főbb, általánosabb ágairól is, mint amilyen az imperatív és deklaratív vonal, és persze sok más fontos és érdekes megközelítés is akad. Konkurens, esemény-vezérelt, tömb-központú, rekurzív – hogy csak néhányat említsek –, melyek közül nem egy szervesen kapcsolódik a fent tárgyalt esetekhez is. Elég nehéz témába vágtam ugyanakkor, próbáltam óvatosan egyensúlyozni a hozzáértőbb és a lelkesen érdeklődő olvasóim igényei között. A fentiek jelenthetnek ugyanakkor némi kapaszkodót további programozással és programnyelvekkel foglalkozó írásokhoz, írásaimhoz is. Jutalmul, hogy végigolvastad ezt a bejegyzést, amely minden mesterkedésem ellenére is kikandikál a bulvárból, íme a rollerező Peter Dinklage a.k.a. Tyrion Lannister!
