Paradigma e programimit

Një **paradigmë e programimit** është një mënyrë relative e nivelit të lartë për të konceptuar dhe strukturuar për zbatimin e një programi kompjuterik. Gjuha e programimit mund të klasifikohet si mbështetëse e një ose më shumë paradigmave.

Paradigmat ndahen dhe përshkruhen nga dimensione të ndryshme të programimit. Disa paradigma kanë të bëjnë me implikimet e modelit të ekzekutimit, të tilla si lejimi i efekteve anësore, ose nëse sekuenca e operacioneve përcaktohet nga modeli i ekzekutimi, ku disa të tjera kanë të bëjnë me mënyrën e organizimit të kodit, të tilla si grupimi në njësi. Megjithatë shumë prej tyre kanë të bëjnë me sintaksën dhe gramatikën.

Disa paradigma të zakonshme të programimit përfshijnë (shembulli i dhënë në mënyrë hierarkike):

* Imperative – kodi kontrollon drejtpërdrejt rrjedhën e ekzekutimit dhe ndryshimin e gjendjes, deklarata të qarta që ndryshojnë gjendjen e programit
** procedurale – të organizuara si procedura që thërrasin njëra-tjetrën
** i orientuar nga objekti – i organizuar si objekte që përmbajnë strukturën e të dhënave dhe sjelljen shoqëruese, përdor struktura të dhënash që përbëhen nga fusha dhe metoda të të dhënave së bashku me ndërveprimet (objektet) e tyre për të dizajnuar programe
*** Programim i bazuar në klasë – i orientuar nga objekti, në të cilin trashëgimia arrihet duke përcaktuar klasat e objekteve, kundrejt vetë objekteve
*** Programim i bazuar në prototipe – i orientuar nga objekti që shmang klasat dhe zbaton trashëgiminë nëpërmjet klonimit të instancave
* Deklarative – kodi deklaron vetitë e rezultatit të dëshiruar, por jo mënyrën e llogaritjes së tij, përshkruan se çfarë llogaritje duhet të kryejë, pa specifikuar ndryshimet e detajuara të gjendjes së programimit imperativ (programimi funksional dhe logjik janë nëngrupet kryesore të programimit deklarativ)
** funksionale – një rezultat i dëshiruar deklarohet si vlera e një sërë vlerësimesh funksionesh, përdor vlerësimin e funksioneve matematikore dhe shmang të dhënat e gjendjes dhe të ndryshueshme
** logjika – një rezultat i dëshiruar deklarohet si përgjigje për një pyetje në lidhje me një sistem faktesh dhe rregullash, përdor logjikë të qartë matematikore për programim
** reaktive – një rezultat i dëshiruar deklarohet me rrjedhat e të dhënave dhe përhapjen e ndryshimit
* Programimi i njëkohshëm – të ketë konstruksione gjuhësore për konkurencë, këto mund të përfshijnë multi-threading, mbështetje për llogaritjen e shpërndarë, kalimin e mesazheve, burime të përbashkëta (përfshirë shared memory)
** Programimi actor – llogaritje e njëkohshme me *aktorët* që marrin vendime lokale në përgjigje të mjedisit (të aftë për sjellje egoiste ose konkurruese)
* Programimi i kufizuar – marrëdhëniet ndërmjet variablave shprehen si kufizime (ose rrjete kufizimesh), zgjidhje të lejuara drejtuese (përdor p.sh. algoritmin e thjeshtë )
* Programimi Dataflow – rillogaritja e detyruar e formulave kur ndryshojnë vlerat e të dhënave (p.sh. tabelat )
* Programimi i shpërndarë – ka mbështetje për kompjuterë të shumtë autonomë që komunikojnë përmes rrjeteve kompjuterike
* Programimi gjenerik – përdor algoritme të shkruara në terma të llojeve që do të specifikohen më vonë, të cilat më pas instancohen sipas nevojës për lloje të veçanta të ofruara si parametra
* Metaprogramimi – shkrimi i programeve që shkruajnë ose manipulojnë programe të tjera (ose vetën e tyre) si të dhëna të tyre, ose që kryejnë një pjesë të punës në kohën e kompilimit që përndryshe do të bëhej në kohën e ekzekutimit
** Metaprogramimi shabllon – metoda metaprogramimi në të cilat një kompiler përdor shabllone për të gjeneruar kodin burimor të përkohshëm, i cili bashkohet nga përpiluesi me pjesën tjetër të kodit burimor dhe më pas kompilohet
** Programimi reflektues – metoda metaprogramimi në të cilat një program modifikon ose zgjeron vetveten
* Programimi Pipeline – një ndryshim i thjeshtë sintakse për të shtuar sintaksë në thirrjet e funksionit fole në gjuhën e krijuar fillimisht pa asnjë
* Programimi rule-based– një rrjet rregullash të përbashkëta që përbëjnë një bazë njohurish dhe mund të përdoren për sisteme ekspertësh dhe për deduktimin dhe zgjidhjen e problemeve
* Programimi vizual – manipulimi i elementeve të programit në mënyrë grafike dhe jo duke i specifikuar ato tekstuale (p.sh. Simulink ); i quajtur edhe *programim diagramatik*

majtas|parapamje|250x250px|Vështrim i përgjithshëm i paradigmave të ndryshme të programimit sipas Peter Van Roy
Paradigmat e programimit vijnë nga kërkimi nga shkencat kompjuterike në praktikat ekzistuese të zhvillimit të softuerit. Gjetjet lejojnë përshkrimin dhe krahasimin e praktikave të programimit dhe gjuhëve të përdorura për kodimin e programeve. Për perspektivë, kërkime të tjera studiojnë proceset e inxhinierisë softuerike dhe përshkruajnë metodologji të ndryshme për t'i përshkruar dhe krahasuar ato.

Një gjuhë programimi mund të përshkruhet në terma të paradigmave. Disa gjuhë mbështesin vetëm një paradigmë: Smalltalk që mbështet programimin e orientuar në objekte dhe Haskell që mbështet metodën funksionale. Shumica e gjuhëve mbështesin paradigma të shumta: një program i shkruar në C++, Object Pascal, ose PHP mund të jetë thjesht procedural, thjesht i orientuar në objekte, ose mund të përmbajë aspekte të të dyja paradigmave, ose të tjera.

Kur përdorni një gjuhë që mbështet paradigma të shumta, zhvilluesi zgjedh se cilat elemente të paradigmes të përdorë. Por, kjo zgjedhje mund të mos përfshijë marrjen në konsideratë të paradigmave në vetvete, zhvilluesi shpesh përdor veçoritë e një gjuhe ashtu siç i ofron gjuha dhe në masën që zhvilluesi i njeh ato.

Gjuhët e kategorizuara si **paradigmë imperative** kanë dy veçori kryesore: deklarojnë rendin në të cilin ndodhin operacionet, me konstruksione që kontrollojnë në mënyrë eksplicite atë rend, dhe ato lejojnë efekte anësore, në të cilat gjendja mund të modifikohet në një moment në kohë, brenda një njësie kodi.

Në të kundërt, gjuhët në **paradigmën deklarative** nuk tregojnë rendin në të cilin duhet të ekzekutohen operacionet. Në vend të kësaj, ato ofrojnë një numër operacionesh të disponueshme në sistem, së bashku me kushtet në të cilat secili lejohet të ekzekutojë. Zbatimi i modelit të ekzekutimit të gjuhës gjurmon se cilat operacione janë të lira për t'u ekzekutuar dhe zgjedh rendin në mënyrë të pavarur.

Në programimin **e orientuar nga objekti**, kodi organizohet në objekte që përmbajnë gjendje që zotërohet dhe (zakonisht) kontrollohet nga kodi i objektit. Shumica e gjuhëve të orientuara nga objekti janë gjithashtu gjuhë imperative.

Në programimin e orientuar nga objekti, programet trajtohen si një grup objektesh ndërvepruese. Në programimin funksional, programet trajtohen si një sekuencë e vlerësimeve të funksioneve.

Shumë paradigma programimi janë po aq të njohura për teknikat që *i ndalojnë* sa edhe për ato që *mbështesin* . Për shembull, programimi i pastër funksional nuk lejon efektet anësore, ndërsa programimi i strukturuar nuk lejon konstruktin goto. Pjesërisht për këtë arsye, paradigmat e reja shpesh konsiderohen si doktrinare ose tepër të ngurta nga ata që janë mësuar me të vjetrat. Megjithatë, shmangia e disa teknikave mund ta bëjë më të lehtë kuptimin e sjelljes së programit dhe vërtetimin e teoremave rreth korrektësisë së programit.

Paradigmat e programimit mund të krahasohen gjithashtu me *modelet e programimit*, të cilat lejojnë thirrjen e një modeli ekzekutimi duke përdorur vetëm një API. Modelet e programimit gjithashtu mund të klasifikohen në paradigma bazuar në veçoritë e modelit të ekzekutimit.

Për llogaritjen paralele, përdorimi i një modeli programimi në vend të një gjuhe është i zakonshëm. Arsyeja është se detajet e harduerit paralel rrjedhin në abstraksionet e përdorura për programimin e harduerit. Kjo bën që programuesi të duhet të hartojë modelet në algoritëm në modelin e ekzekutimit (të cilat janë futur për shkak të rrjedhjes së harduerit në abstraksion). Si pasojë, asnjë gjuhë programimi paralele nuk përshtatet mirë me të gjitha problemet e llogaritjes. Kështu, është më e përshtatshme të përdoret një gjuhë bazë sekuenciale dhe të futen thirrjet API në modelet e ekzekutimit paralel nëpërmjet një modeli programimi. Modele të tilla programimi paralel mund të klasifikohen sipas abstraksioneve që pasqyrojnë harduerin, të tilla si shared memory, distributed memory me message passing etj. Këto mund të konsiderohen shije të paradigmës së programimit që zbatohen vetëm për gjuhët paralele dhe modelet e programimit.

## Kritika 
Disa studiues të gjuhëve të programimit kritikojnë nocionin e paradigmave si një klasifikim i gjuhëve programuese, p.sh. Harper, dhe Krishnamurthi. Ata argumentojnë se shumë gjuhë programimi nuk mund të klasifikohen rreptësisht në një paradigmë, por përkundrazi përfshijnë veçori nga disa paradigma.

## Historia 
Qasje të ndryshme ndaj programimit janë zhvilluar me kalimin e kohës. Klasifikimi i secilës qasje ose u përshkrua në kohën kur qasja u zhvillua për herë të parë, por shpesh jo deri pak kohë më vonë, në mënyrë retrospektive. Një qasje e hershme e identifikuar me vetëdije si e tillë është programimi i strukturuar, i përkrahur që nga mesi i viteve 1960. Koncepti i një *paradigme programimi* si e tillë daton të paktën në vitin 1978, në leksionin e çmimit Turing të Robert W. Floyd, të titulluar si *The Paradigms of Programming*, i cili citon nocionin e paradigmës siç përdoret nga Thomas Kuhn në *The Structure of Scientific Revolutions* (1962). Gjuhët e hershme të programimit nuk kishin paradigma programimi të përcaktuara qartë dhe ndonjëherë programet përdorën gjerësisht deklaratat goto.  Kjo çoi në zhvillimin e paradigmave të strukturuara të programimit që ndalonin përdorimin e deklaratave goto; duke lejuar vetëm përdorimin e konstrukteve programuese më të strukturuara.

## Gjuhët dhe paradigmat 
### Kodi i makinës 
Kodi i makinës është niveli më i ulët i programimit kompjuterik pasi janë udhëzimet e makinës që përcaktojnë sjelljen në nivelin më të ulët të abstraktit të mundshëm për një kompjuter. Meqenëse është mënyra më e përshkruar për të koduar, ajo klasifikohet si imperative.

Njihet ndryshe edhe me emrin gjuha programuese e gjeneratës së parë .

### Assembly 
Gjuha assembly prezantoi mnemonikën për udhëzimet e makinës dhe adresat e kujtesës. Asambleja klasifikohet si imperative dhe nganjëherë quhet gjuha programuese e gjeneratës së dytë.

Në vitet 1960, gjuhët e asamblesë u zhvilluan për të mbështetur bibliotekën COPY dhe aftësitë mjaft të sofistikuara të gjenerimit dhe përpunimit makro të kushtëzuar, CALL në nënprogram, variabla të jashtëm dhe seksione të zakonshme, duke mundësuar ripërdorim të konsiderueshëm të kodit dhe izolim nga specifikat e harduerit nëpërmjet përdorimit të operatorë logjikë si READ/WRITE/GET/PUT. Asambleja u përdor dhe ende përdoret për sistemet kritike për kohën dhe shpesh në sistemet e integruara pasi jep kontrollin më të madh të asaj që bën makina.

### Gjuhët procedurale 
Gjuhët procedurale, të cilat quhen edhe si gjuhët e programimit të gjeneratës së tretë, janë gjuhët e para të përshkruara si gjuhë të nivelit të lartë . Ata mbështesin fjalorin në lidhje me problemin që zgjidhet.

* COmmon Business Oriented Language (COBOL)përdor terma si file, move dhe copy .
* FORmula TRANslation (FORTRAN)duke përdorur terminologjinë e gjuhës matematikore, ajo u zhvillua kryesisht për probleme shkencore dhe inxhinierike.
* ALGOrithmic Language (ALGOL)fokusuar në të qenit një gjuhë e përshtatshme për të përcaktuar algoritmet, ndërkohë që përdor terminologjinë e gjuhës matematikore, duke synuar probleme shkencore dhe inxhinierike, ashtu si FORTRAN.
* Programming Language One (PL/I)një gjuhë hibride për qëllime të përgjithshme komerciale-shkencore mbështetëse .
* Beginners All purpose Symbolic Instruction Code (BASIC) – është zhvilluar për të mundësuar më shumë njerëz të shkruajnë programe.
* Cnjë gjuhë programimi për qëllime të përgjithshme, e zhvilluar fillimisht nga Dennis Ritchie midis 1969 dhe 1973 në AT&amp;amp;T Bell Labs .

Këto gjuhë klasifikohen si paradigmë procedurale. Ata kontrollojnë drejtpërdrejt procesin hap pas hapi që ndjek një program kompjuterik. Prandaj, efikasiteti i një programi të tillë varet shumë nga aftësitë e programuesit.

### Programimi i orientuar nga objektet 
Në përpjekje për të përmirësuar gjuhët procedurale, u krijuan gjuhë programimi i orientuar nga objektetet (OOP), të tilla si Simula, Smalltalk, C++, Eiffel, Python, PHP, Java dhe C# . Në këto gjuhë, të dhënat dhe metodat për të manipuluar të dhënat janë në të njëjtën njësi kodi të quajtur objekt . Ky enkapsulim siguron që e vetmja mënyrë që një objekt mund të aksesojë të dhënat është nëpërmjet *metodave* të objektit që përmban të dhënat. Kështu, funksionimi i brendshëm i një objekti mund të ndryshohet pa ndikuar në kodin që përdor objektin.

Ka polemika të ngritura nga Alexander Stepanov, Richard Stallman dhe programues të tjerë, në lidhje me efikasitetin e paradigmës OOP kundrejt paradigmës procedurale.

Megjithëse shumica e gjuhëve OOP janë të gjeneratës së tretë, është e mundur të krijohet një gjuhë assembler e orientuar nga objekti. High Level Assembly(HLA) është një shembull i kësaj që mbështet plotësisht llojet e avancuara të të dhënave dhe programimin e gjuhës asambleje të orientuar nga objektipavarësisht origjinës së hershme.  Krahasimet e sakta të efikasitetit të paradigmave konkurruese shpesh bëhen më të vështira për shkak të terminologjisë së re dhe të ndryshme të aplikuar për entitete dhe procese të ngjashme së bashku me dallimet e shumta të zbatimit nëpër gjuhë.

### Gjuhët deklarative 
Një program programimi deklarativ përshkruan se cili është problemi, jo si ta zgjidhim atë. Programi është strukturuar si një grup karakteristikash për t'u gjetur në rezultatin e pritur, jo si një procedurë që duhet ndjekur. Duke pasur parasysh një bazë të dhënash ose një grup rregullash, kompjuteri përpiqet të gjejë një zgjidhje që përputhet me të gjitha vetitë e dëshiruara. Një arketip i një gjuhe deklarative është gjuha e gjeneratës së katërt SQL,  familja e gjuhëve funksionale dhe programimi logjik.

Programimi funksional është një nëngrup i programimit deklarativ. Programet e shkruara duke përdorur këtë paradigmë përdorin funksione, blloqe kodi që synojnë të sillen si funksione matematikore. Gjuhët funksionale dekurajojnë ndryshimet në vlerën e variablave përmes caktimit, duke bërë një përdorim të madh të rekursionit .

Paradigma e programimit logjik e sheh llogaritjen si arsyetim të automatizuar mbi një grup njohurish. Faktet rreth fushës së problemit shprehen si formula logjike, dhe programet ekzekutohen duke aplikuar rregulla konkluzionesh mbi to derisa të gjendet një përgjigje për problemin, ose grupi i formulave të provohet jo konsistent.

### Paradigma të tjera 
Programimi simbolik është një paradigmë që përshkruan programet në gjendje të manipulojnë formulat dhe komponentët e programit si të dhëna.

Programimi i diferencueshëm strukturon programet në mënyrë që ato të mund të diferencohen në të gjithë, zakonisht nëpërmjet diferencimit automatik .

Programimi i shkolluar, si një formë e programimit imperativ, i strukturon programet si një rrjet me në qendër njeriun.

Teknikat simbolike të tilla si reflektimi, të cilat lejojnë programin t'i referohet vetvetes, mund të konsiderohen gjithashtu si një paradigmë programimi. Megjithatë, kjo është në përputhje me paradigmat kryesore dhe kështu nuk është një paradigmë reale më vete.

## Referime