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:

; Geef een lijst van alle boeken met ten minste THRESHOLD verkochte exemplaren. (definieer (best-selling-books drempel) (filter (lambda (book) (>= (book-sales book) drempel))      book-list))

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:

// Geef een lijst van alle boeken met ten minste 'drempel' verkochte exemplaren. functie bestverkochte-boeken(drempel) { retourneer bookList. filter( functie(boek) { retourneer boek. verkoop >= drempel; } ); }

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:

; Geef een functie terug die de afgeleide van f benadert ; met behulp van een interval van dx, dat voldoende klein moet zijn. (definieer (afgeleide f dx)) (lambda (x) (/ (- (f (+ x dx)) (f x)) dx))

In ECMAScript:

// Geef een functie terug die de afgeleide van f benadert // met behulp van een interval van dx, dat voldoende klein moet zijn. functie afgeleide(f, dx) { functie(x) {return(f(x + dx) - f(x)) / dx; }; }

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:

# Geef een functie terug die de afgeleide van f # benadert met behulp van een interval van dx, dat voldoende klein moet zijn. def derivative(f, dx): def gradient(x): return (f(x + dx) - f(x)) / dx terug gradiënt

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.

def afgeleide(f, dx): return lambda x: (f(x + dx) - f(x)) / dx

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

(definieer foo #f) (definieer bar #f) (laat ((geheim-bericht "geen")) (set! foo (lambda (msg) (set! geheim-bericht msg)) (set! bar (lambda () geheim-bericht))) (display (bar)) ; drukt "geen" af (newline) (foo "ontmoet me bij de dokken om middernacht") (display (bar)) ; drukt "ontmoet me bij de dokken om middernacht" af
  • 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.

AlegsaOnline.com - 2020 / 2023 - License CC3