Uzáver je v programovaní špecifický druh funkcie, ktorý okrem svojho telesa obsahuje aj referenciu na svoj lexikálny kontext — teda na premenné, ktoré boli zviazané v čase vytvorenia. Inak povedané, uzáver kombinujesámotnú funkciu s prostredím, ktoré ukladá hodnoty jej viazaných mien. Táto vlastnosť umožňuje, aby funkcia „pamätala“ stav medzi volaniami bez použitia globálnych premenných.
Hlavné charakteristiky
- Lexikálne viazanie: uzáver drží odkazy na premenné zo svojho vonkajšieho bloku, nie na premenné podľa mena pri volaní.
- Životnosť údajov: hodnota viazaných premenných žije tak dlho, ako žije uzáver, aj keď pôvodný rozsah (scope) skončil.
- Prvotriedne funkcie: jazyky, ktoré umožňujú priradzovať funkcie do premenných, vracať ich z iných funkcií a odovzdávať ako argumenty, zvyčajne podporujú uzávery.
Krátka história a pôvod pojmu
Pojem "closure" sa pripisuje Petru J. Landinovi v 60. rokoch 20. storočia. V praktickom programovaní sa uzávery výraznejšie rozšírili so vzostupom funkcionálnych jazykov; jeden z kľúčových momentov bol popularizovaný jazykom Scheme, často odkazovaným v literatúre aj cez historické materiály o Scheme. Dnes sú uzávery súčasťou mnohých moderných jazykov od skriptovacích po silno typované jazyky.
Použitie a príklady významu
Uzávery sa využívajú tam, kde je potrebné udržať súkromný stav alebo vytvoriť funkcie s predplnenými argumentmi (partial application). Typické scenáre zahŕňajú:
- Funkčné továrne — funkcia vracia inú funkciu, ktorá si pamätá parametre z okolitého volania.
- Callbacky a event handlery — keď callback potrebuje prístup k lokálnym hodnotám zo svojho pôvodného kontextu.
- Enkapsulácia stavu bez tried — uzávery umožnia „súkromné“ premenné bez použitia objektov.
Rozdiely a bežné omyly
Nie každý anonymný (bezmenný) blok kódu je uzáver. Anonymná funkcia je uzáver iba vtedy, keď zachytáva aspoň jednu viazanú premennú zo svojho vonkajšieho prostredia. Ak anonymná funkcia neodkazuje na žiadne vonkajšie premenné, nejde o uzáver. V praxi sa preto často zamieňajú pojmy anonymná funkcia a uzáver, čo vedie k terminologickým nejasnostiam.
Implementačné poznámky a obmedzenia
Realizácia uzáverov závisí od runtime a kompilátora jazyka. Niektoré implementácie alokujú zachytené premenné na halde, iné používajú optimalizácie pre prípad, že uzávery nie sú dlho živé. Pri práci s uzávierkami treba byť opatrný pri zdieľaní premenných medzi viacerými uzávermi (tzv. capturing by reference vs. by value), pretože môže viesť k neočakávanému správaniu, ak sa hodnota v priebehu času mení.
Ďalšie informácie a technické detaily možno nájsť v literatúre a online zdrojoch: úvod k uzáverom, príklady implementácií v rôznych jazykoch: funkcie a uzávery, ukážky v jazyku: Scheme a ďalšie porovnania: história a vývoj. Pre rozdiel medzi anonymnými funkciami a uzávermi pozrite: anonymné funkcie.