Closure
In de informatica is een closure een functie die een eigen omgeving heeft. In deze omgeving bevindt zich ten minste één gebonden variabele (een naam die een waarde heeft, zoals een getal). De omgeving van de closure houdt de gebonden variabelen in het geheugen tussen het gebruik van de closure.
Peter J. Landin gaf dit idee de naam closure in 1964. De programmeertaal Scheme maakte closures populair na 1975. Veel programmeertalen die na die tijd zijn gemaakt hebben closures.
Anonieme functies (functies zonder naam) worden soms ten onrechte closures genoemd. De meeste talen die anonieme functies hebben, hebben ook closures. Een anonieme functie is ook een closure als hij een eigen omgeving heeft met ten minste één gebonden variabele. Een anonieme functie zonder eigen omgeving is geen closure. Een named closure is niet anoniem.
Sluitingen en eersteklas functies
Waarden kunnen getallen zijn of een ander soort gegevens, zoals letters, of gegevensstructuren die uit eenvoudiger delen bestaan. In de regels van een programmeertaal zijn de eersteklas waarden waarden die aan functies kunnen worden gegeven, door functies kunnen worden teruggegeven, en aan een variabelenaam kunnen worden gebonden. Functies die andere functies aannemen of teruggeven worden hogere-orde functies genoemd. De meeste talen die functies als eerste-orde waarden hebben, hebben ook hogere-orde functies en closures.
Kijk bijvoorbeeld eens naar de volgende Scheme-functie:
In dit voorbeeld is de lambda expressie (lambda (book) (>= (book-sales book) threshold)) onderdeel
van de functie best-selling-books.
Wanneer de functie wordt uitgevoerd, moet Scheme de waarde van de lambda maken. Het doet dit door een closure te maken met de code voor de lambda en een verwijzing naar de drempel
variabele, die een vrije variabele is binnen de lambda. (Een vrije variabele is een naam die niet gebonden is aan een waarde).
De filterfunctie voert de afsluiting vervolgens uit op elk boek in de lijst om te bepalen welke boeken moeten worden teruggegeven. Omdat de afsluiting zelf een verwijzing naar threshold
heeft, kan de afsluiting die waarde gebruiken elke keer dat filter
de afsluiting uitvoert. De functie filter
zelf kan in een geheel apart bestand worden geschreven.
Hier is hetzelfde voorbeeld herschreven in ECMAScript (JavaScript), een andere populaire taal met ondersteuning voor closures:
ECMAScript gebruikt hier het woord function
in plaats van lambda
, en de Array.filter
methode in plaats van de filter
functie, maar verder doet de code hetzelfde op dezelfde manier.
Een functie kan een afsluiting creëren en deze teruggeven. Het volgende voorbeeld is een functie die een functie teruggeeft.
In regeling:
In ECMAScript:
De closure omgeving behoudt de gebonden variabelen f
en dx
nadat de omsluitende functie (afgeleide
) terugkomt. In talen zonder afsluitingen zouden deze waarden verloren gaan nadat de afsluitende functie terugkomt. In talen met closures moet een gebonden variabele in het geheugen blijven zolang een closure deze heeft.
Een closure hoeft niet gevormd te worden met een anonieme functie. De programmeertaal Python, bijvoorbeeld, heeft beperkte ondersteuning voor anonieme functies, maar kent wel closures. Bijvoorbeeld, één manier waarop het bovenstaande ECMAScript voorbeeld zou kunnen worden geïmplementeerd in Python is:
In dit voorbeeld maakt de functie met de naam gradient een sluiting samen met de variabelen f en dx. De buitenste omsluitende functie genaamd afgeleide retourneert deze afsluiting. In dit geval zou een anonieme functie ook werken.
Python moet in plaats daarvan vaak named functions gebruiken, omdat zijn lambda-expressies alleen andere expressies mogen bevatten (code die een waarde teruggeeft) en geen statements (code die effecten heeft maar geen waarde). Maar in andere talen, zoals Scheme, retourneert alle code een waarde; in Scheme is alles een expressie.
Gebruik van sluitingen
Sluitingen hebben vele toepassingen:
- Ontwerpers van software bibliotheken kunnen gebruikers toestaan om gedrag aan te passen door closures als argumenten aan belangrijke functies door te geven. Bijvoorbeeld, een functie die waarden sorteert kan een closure argument accepteren dat de te sorteren waarden vergelijkt volgens een door de gebruiker gedefinieerd criterium.
- Omdat closures de evaluatie vertragen - d.w.z. ze "doen" niets totdat ze aangeroepen worden - kunnen ze gebruikt worden om controlestructuren te definiëren. Bijvoorbeeld, alle standaard controle structuren van Smalltalk, inclusief branches (if/dan/else) en loops (while en for), worden gedefinieerd met behulp van objecten waarvan de methoden closures accepteren. Gebruikers kunnen ook gemakkelijk hun eigen controlestructuren definiëren.
- Er kunnen meerdere functies worden geproduceerd die over dezelfde omgeving sluiten, zodat zij privé met elkaar kunnen communiceren door die omgeving te veranderen (in talen die opdracht toelaten).
In regeling
- Closures kunnen worden gebruikt om object systemen te implementeren.
Opmerking: Sommige sprekers noemen elke gegevensstructuur die een lexicale omgeving bindt een closure, maar de term verwijst gewoonlijk specifiek naar functies.
Vragen en antwoorden
V: Wat is een afsluiting in de informatica?
A: Een closure is een functie die een eigen omgeving heeft.
V: Wat bevat de omgeving van een closure?
A: De omgeving van een closure bevat ten minste één gebonden variabele.
V: Wie gaf het idee van closure zijn naam?
A: Peter J. Landin gaf het idee van closure zijn naam in 1964.
V: Welke programmeertaal maakte closures populair na 1975?
A: De programmeertaal Scheme maakte closures populair na 1975.
V: Zijn anonieme functies en closures hetzelfde?
A: Anonieme functies worden soms ten onrechte closures genoemd, maar niet alle anonieme functies zijn closures.
V: Wat maakt een anonieme functie tot een closure?
A: Een anonieme functie is een closure als hij een eigen omgeving heeft met ten minste één gebonden variabele.
V: Is een named closure anoniem?
A: Nee, een named closure is niet anoniem.