Programimi funksional

Në shkencën kompjuterike, **programimi funksional** është një paradigmë programimi ku programet ndërtohen duke zbatuar dhe përbërë funksione . Është një paradigmë programimi deklarative në të cilën përkufizimet e funksioneve janë pemë shprehjesh që krahasojnë disa vlera me vlera të tjera, në vend të një vargu deklaratash imperative që përditësojnë gjendjen e ekzekutimit të programit.

Në programimin funksional, funksionet trajtohen si qytetarë të klasit të parë, që do të thotë se ato mund të lidhen me emrat (duke përfshirë identifikuesit lokal), të kalohen si argumenta dhe të kthehen nga funksione të tjera, ashtu si çdo lloj tjetër i të dhënave . Kjo veqori mundeson që programet të shkruhen në një stil deklarativ dhe kompozues (të përbërë), ku funksionet e vogla kombinohen në një mënyrë modulare për të krijuar logjikë më komplekse.

Programimi funksional shpesh trajtohet si sinonim i programimit të pastër funksional, një nëngrup i programimit funksional qe i trajton të gjitha funksionet si funksione matematikore përcaktuese ose funksione të pastra . Kur një funksion i pastër thirret me disa argumente të dhëna, ai gjithmonë do të kthejë të njëjtin rezultat dhe nuk mund të ndikohet nga ndonjë gjendje e ndryshueshme ose efekte të tjera anësore . Kjo është në kontrast me procedurat e papastra, të zakonshme në programimin imperativ, të cilat mund të kenë efekte anësore (të tilla si modifikimi i gjendjes së programit ose marrja e të dhënave nga një përdorues). Përkrahësit e programimit thjesht funksional argumentojne se duke kufizuar efektet anësore, programet mund të kenë më pak gabime, të jenë më të lehta për tu bërë debug dhe testuar dhe më të përshtatshëm për verifikim zyrtar .

Programimi funksional i ka rrënjët në akademi, duke evoluar nga llogaritja lambda, një sistem formal i llogaritjes i bazuar vetëm tek funksionet. Programimi  funksional ka qënë historikisht më pak popullor se ai imperativ, por shumë gjuhë funksionale po gjejnë përdorim gjithnjë edhe më shumë në industri dhe arsim , duke përfshire Common Lisp, Scheme, Clojure, Wolfram Language, Racket, Erlang, Elixir, OCaml, Haskell, and F#. Lean është një gjuhë programimi e përdorur rëndom për të provuar teoremat matematikore. Programimi funksional është gjithashtu kyç në disa gjuhë që kanë/kanë patur sukses në fusha specifike, si JavaScript në Web, R në statistikë, J, K dhe Q në analizë financiare, dhe XQuery/XSLT për XML. Gjuhë të tilla si SQL dhe Lex/Yacc përdorin elemente të programimit funksional, psh moslejimi i vlerave të ndryshueshme. Gjithashtu, shumë gjuhë të tjera programimi mbështesin një stil funksional ose kanë implementuar veçori nga programimi funksional si psh C++11, C#, Kotlin, Perl, PHP, Python, Go, Rust, Raku, Scala dhe Java (që prej Java 8).

## Konceptet 
Një numër konceptesh  dhe paradigmash janë specifike për programimin funksional dhe përgjithësisht të huaja për programimin imperativ (përfshirë programimin e orientuar nga objekti ). Sidoqoftë, gjuhët e programimit shpesh ofrojnë disa paradigma programimi, kështu që programuesit që përdorin gjuhë "kryesisht imperative" mund të kenë përdorur disa nga këto koncepte.

### Funksione të klasit të parë dhe të rendit të lartë 
Funksionet e rendit të lartë janë funksione që ose mund të marrin funksione të tjera si argumente ose t'i kthejnë ato si rezultate. Në llogaritje, një shembull i një funksioni të rendit të lartë është operatori diferencial d/dx, i cili kthen derivatin e një funksioni f .

Funksionet e rendit më të lartë janë të lidhura ngushtë me funksionet e klasit të parë sepse që funksionet e rendit më të lartë dhe funksionet e klasit të parë lejojnë funksione si argumente dhe rezultate të funksioneve të tjera. Dallimi midis të dyjave është delikat: "i rendit të lartë" përshkruan një koncept matematikor të funksioneve që veprojnë mbi funksione të tjera, ndërsa "klasi i parë" është një term i shkencës kompjuterike për entitetet e gjuhës së programimit që nuk kanë kufizime në përdorimin e tyre (pra funksionet e klasit të parë mund të shfaqen kudo në program aty ku munden entitete të tjera të klasit të parë si numrat, duke përfshirë si argumente për funksionet e tjera dhe si vlerat e tyre të kthimit).

### Funksione të pastra 
Funksionet (ose shprehjet) e pastra nuk kanë efekte anësore (kujtesë ose I/O). Kjo do të thotë që funksionet e pastra kanë disa veti të dobishme, shumë prej të cilave mund të përdoren për të optimizuar kodin:

* Nëse rezultati i një shprehjeje të pastër nuk përdoret, ai mund të hiqet pa i prekur shprehjet e tjera.
* Nëse një funksion i pastër thirret me argumente që nuk shkaktojnë efekte anësore, rezultati është konstante në lidhje me atë listë argumentesh (ndonjëherë quhet transparencë referenciale ose idempotencë ), dmth, thirrja e funksionit të pastër përsëri me të njëjtat argumente kthen të njëjtin rezultat.
* Nëse nuk ka varësi të të dhënave midis dy shprehjeve të pastra, rendi i tyre mund të përmbyset, ose mund të kryhen paralelisht dhe nuk mund të ndërhyjnë me njëra-tjetrën (me terma të tjerë, vlerësimi i çdo shprehjeje të pastër është i sigurt në thread ).
* Nëse e gjithë gjuha nuk lejon efekte anësore, atëherë mund të përdoret çdo strategji vlerësimi; kjo i jep kompajlerit lirinë për të rirenditur ose kombinuar vlerësimin e shprehjeve në një program (për shembull, duke përdorur shpyllëzimin ).

### Rekursioni 
Iterimi (looping) në gjuhët funksionale zakonisht realizohet nëpërmjet rekursionit . Funksionet rekursive thirren në vetvete, duke lënë një veprim të përsëritet derisa të arrijë në rastin bazë . Në përgjithësi, rekursioni kërkon mbajtjen e një stive, e cila konsumon hapësirë në një sasi lineare deri në thellësinë e rekursionit. Kjo mund ta bëjë rekursionin jashtëzakonisht të shtrenjtë për t'u përdorur në vend të laqeve imperative. Megjithatë, një formë e veçantë e rekursionit e njohur si rekursioni i bishtit Mund të njihet dhe optimizohet nga një përpilues, ashtu si përsëritja në gjuhët imperative. Optimizimi i rekursionit të bishtit realizohet shpesh duke transformuar programin në stilin e kalimit të vazhdimit gjatë përpilimit.

## Referime