Lukning (datalogi)
Inden for datalogi er en lukning en funktion, der har sit eget miljø. I dette miljø er der mindst én bundet variabel (et navn, der har en værdi, f.eks. et tal). Lukningens miljø opbevarer de bundne variabler i hukommelsen mellem lukningens brug.
Peter J. Landin gav denne idé navnet lukning i 1964. Programmeringssproget Scheme gjorde closures populære efter 1975. Mange programmeringssprog, der er udviklet efter denne tid, har closures.
Anonyme funktioner (funktioner uden navn) kaldes nogle gange fejlagtigt for closures. De fleste sprog, der har anonyme funktioner, har også closures. En anonym funktion er også en lukning, hvis den har sit eget miljø med mindst én bundet variabel. En anonym funktion uden eget miljø er ikke en lukning. En navngiven lukning er ikke anonym.
Lukninger og førsteklasses funktioner
Værdier kan være tal eller en anden type data, f.eks. bogstaver, eller datastrukturer, der består af enklere dele. I reglerne for et programmeringssprog er førsteklasses værdier værdier, der kan gives til funktioner, returneres af funktioner og bindes til et variabelnavn. Funktioner, der tager eller returnerer andre funktioner, kaldes funktioner af højere orden. De fleste sprog, der har funktioner som førsteklassesværdier, har også funktioner af højere orden og closures.
Se f.eks. på følgende Scheme-funktion:
I dette eksempel er lambda-udtrykket (lambda (book) (>= (book-sales book) threshold)))
en del af funktionen best-selling-books
. Når funktionen køres, skal Scheme lave værdien af lambdaen. Det gør det ved at lave en closure med koden for lambdaen og en henvisning til tærskelvariablen, som er en fri variabel inden for lambdaen. (En fri variabel er et navn, der ikke er bundet til en værdi).
Filterfunktionen kører derefter lukningen på hver bog på listen for at vælge, hvilke bøger der skal returneres. Da lukningen selv har en reference til tærskelværdien
, kan lukningen bruge denne værdi, hver gang filteret
kører lukningen. Selve filterfunktionen
kan skrives i en helt separat fil.
Her er det samme eksempel omskrevet i ECMAScript (JavaScript), et andet populært sprog med understøttelse af closures:
ECMAScript bruger ordet funktion
her i stedet for lambda
og Array.
filter-metoden i stedet for filterfunktionen, men ellers gør koden det samme på samme måde.
En funktion kan oprette en lukning og returnere den. Følgende eksempel er en funktion, der returnerer en funktion.
I ordningen:
I ECMAScript:
Lukningsmiljøet beholder de bundne variabler f
og dx,
efter at den omsluttende funktion (afledning
) vender tilbage. I sprog uden lukninger ville disse værdier gå tabt, når den omsluttende funktion vender tilbage. I sprog med lukninger skal en bundet variabel bevares i hukommelsen, så længe en lukning har den.
En lukning behøver ikke nødvendigvis at blive dannet ved hjælp af en anonym funktion. Programmeringssproget Python har f.eks. begrænset understøttelse af anonyme funktioner, men har lukninger. Ovenstående ECMAScript-eksempel kunne f.eks. implementeres i Python på følgende måde:
I dette eksempel danner funktionen gradient en lukning sammen med variablerne f og dx. Den ydre omsluttende funktion ved navn derivative returnerer denne lukning. I dette tilfælde ville en anonym funktion også fungere.
Python skal ofte bruge navngivne funktioner i stedet, fordi lambdaudtryk kun kan indeholde andre udtryk (kode, der returnerer en værdi) og ikke statements (kode, der har virkninger, men ingen værdi). Men i andre sprog, f.eks. i Scheme, returnerer al kode en værdi; i Scheme er alting et udtryk.
Anvendelse af lukninger
Lukninger har mange anvendelsesmuligheder:
- Designere af softwarebiblioteker kan give brugerne mulighed for at tilpasse adfærd ved at sende lukninger som argumenter til vigtige funktioner. En funktion, der sorterer værdier, kan f.eks. acceptere et lukningsargument, der sammenligner de værdier, der skal sorteres, i henhold til et brugerdefineret kriterium.
- Fordi lukninger udskyder evalueringen - dvs. at de ikke "gør" noget, før de bliver kaldt - kan de bruges til at definere kontrolstrukturer. F.eks. er alle Smalltalks standard kontrolstrukturer, herunder forgreninger (if/then/else) og sløjfer (while og for), defineret ved hjælp af objekter, hvis metoder accepterer closures. Brugere kan også nemt definere deres egne kontrolstrukturer.
- Der kan produceres flere funktioner, der er tæt på det samme miljø, hvilket gør det muligt for dem at kommunikere privat ved at ændre dette miljø (i sprog, der tillader tildeling).
I ordningen
- Lukninger kan bruges til at implementere objektsystemer.
Bemærk: Nogle talere kalder enhver datastruktur, der binder et leksikalsk miljø, for en lukning, men udtrykket henviser normalt specifikt til funktioner.
Spørgsmål og svar
Spørgsmål: Hvad er en afslutning i datalogi?
A: En closure er en funktion, der har sit eget miljø.
Spørgsmål: Hvad indeholder en closures miljø?
Svar: En closures miljø indeholder mindst én bundet variabel.
Spørgsmål: Hvem gav ideen om lukning sit navn?
Svar: Peter J. Landin gav navnet til lukningstanken i 1964.
Spørgsmål: Hvilket programmeringssprog gjorde closures populære efter 1975?
Svar: Programmeringssproget Scheme gjorde lukninger populære efter 1975.
Spørgsmål: Er anonyme funktioner og closures det samme?
Svar: Anonyme funktioner kaldes nogle gange fejlagtigt for closures, men ikke alle anonyme funktioner er closures.
Sp: Hvad gør en anonym funktion til en closure?
Svar: En anonym funktion er en lukning, hvis den har sit eget miljø med mindst én bundet variabel.
Sp: Er en navngiven lukning anonym?
Svar: Nej, en navngiven lukning er ikke anonym.