Valorile pot fi numere sau un alt tip de date, cum ar fi litere, sau structuri de date alcătuite din părți mai simple. În regulile unui limbaj de programare, valorile de primă clasă sunt valori care pot fi date funcțiilor, returnate de funcții și legate la un nume de variabilă. Funcțiile care preiau sau returnează alte funcții se numesc funcții de ordin superior. Majoritatea limbajelor care au funcții ca valori de primă clasă au, de asemenea, funcții de ordin superior și închideri.
De exemplu, aruncați o privire la următoarea funcție Scheme:
; Întoarceți o listă a tuturor cărților cu cel puțin TREI exemplare vândute. (define (best-selling-books threshold) (filter (lambda (book) (>= (book-sales book) threshold)) book-list)) book-list))
În acest exemplu, expresia lambda (lambda (lambda (carte) (>= (vânzări de cărți carte) prag))) face parte din funcția best-selling-books. Atunci când funcția este executată, Scheme trebuie să facă valoarea expresiei lambda. Face acest lucru realizând o închidere cu codul pentru lambda și o referință la variabila threshold, care este o variabilă liberă în interiorul lambdei. (O variabilă liberă este un nume care nu este legat de o valoare).
Funcția de filtrare execută apoi închiderea pe fiecare carte din listă pentru a alege cărțile care vor fi returnate. Deoarece închiderea însăși are o referință la prag, închiderea poate utiliza această valoare de fiecare dată când filtrul execută închiderea. Funcția de filtrare în sine poate fi scrisă într-un fișier complet separat.
Iată același exemplu rescris în ECMAScript (JavaScript), un alt limbaj popular cu suport pentru închideri:
// Întoarce o listă cu toate cărțile cu cel puțin 'prag' de exemplare vândute. function bestSellingBooks(threshold) { return bookList. filter( function(book) { return book. sales >= threshold; } ); }
ECMAScript folosește aici cuvântul function în loc de lambda și metoda Array.filter în locul funcției filter, dar în rest codul face același lucru în același mod.
O funcție poate crea o închidere și o poate returna. Următorul exemplu este o funcție care returnează o funcție.
În schemă:
; Returnează o funcție care aproximează derivata lui f ; folosind un interval dx, care ar trebui să fie corespunzător de mic. (definește (derivată f dx) (lambda (x) (/ (- (f (+ x dx))) (f x))) dx))))))
În ECMAScript:
// Se returnează o funcție care aproximează derivata lui f // folosind un interval dx, care trebuie să fie corespunzător de mic. function derivative(f, dx) { return function(x) { return (f(x + dx) - f(x)) / dx; }; }; }
Mediul de închidere păstrează variabilele legate f și dx după ce funcția de închidere (derivată) se întoarce. În limbajele fără închideri, aceste valori s-ar pierde după ce funcția de închidere revine. În limbajele cu închideri, o variabilă legată trebuie să fie păstrată în memorie atâta timp cât o are orice închidere.
Nu este necesar ca o închidere să fie formată cu ajutorul unei funcții anonime. Limbajul de programare Python, de exemplu, are un suport limitat pentru funcțiile anonime, dar are închideri. De exemplu, un mod în care exemplul ECMAScript de mai sus ar putea fi implementat în Python este:
# returnează o funcție care aproximează derivata lui f # folosind un interval de dx, care ar trebui să fie corespunzător de mic. def derivative(f, dx): def gradient(x): return (f(x + dx) - f(x)) / dx return gradient
În acest exemplu, funcția numită gradient realizează o închidere împreună cu variabilele f și dx. Funcția exterioară de închidere numită derivată returnează această închidere. În acest caz, ar funcționa și o funcție anonimă.
def derivative(f, dx): return lambda x: (f(x + dx) - f(x)) / dx
Python trebuie să utilizeze adesea funcții numite în locul acestora, deoarece expresiile lambda pot conține doar alte expresii (cod care returnează o valoare) și nu declarații (cod care are efecte, dar nu are valoare). Dar în alte limbaje, cum ar fi Scheme, tot codul returnează o valoare; în Scheme, totul este o expresie.