Wat Is een zuivere functie?
voordelen
Er zijn verschillende voordelen aan het gebruik van zuivere functies, zowel in termen van prestaties als bruikbaarheid.
leesbaarheid
Pure functies zijn veel gemakkelijker te lezen en te redeneren. Alle relevante ingangen en afhankelijkheden worden geleverd als parameters, zodat er geen effecten worden waargenomen die variabelen veranderen buiten de set van ingangen.
Dit betekent dat we snel een functie en zijn afhankelijkheden kunnen begrijpen, gewoon door de declaratie van de functie te lezen. Dus als een functie wordt gedeclareerd als f(a, b, c)
dan weten we dat alleen a
b
, en c
afhankelijkheden zijn van f
.
portabiliteit
omdat alle afhankelijkheden worden geleverd als invoerparameters en niet toegankelijk zijn via een globale context, kunnen deze afhankelijkheden worden verwisseld afhankelijk van de context waarin de functie wordt aangeroepen.
Dit betekent dat dezelfde functie kan werken op verschillende implementaties van dezelfde bron, bijvoorbeeld.
Dit maakt de code veel draagbaarder en herbruikbaar omdat dezelfde functie in verschillende contexten kan worden gebruikt, in plaats van een andere functie te moeten schrijven om een andere implementatie van dezelfde klasse te gebruiken.
bijvoorbeeld, in plaats van twee verschillende onzuivere functies te moeten schrijven om twee verschillende loggers te gebruiken die globaal zijn opgeslagen, zou een pure functie gewoon de gewenste logger opnemen als invoer.
testen
het ontbreken van bijwerkingen maakt zuivere functies zeer eenvoudig te testen, omdat we alleen hoeven te testen of de ingangen de gewenste uitgangen produceren. We hoeven de geldigheid van een wereldwijde programmastaat niet te controleren in onze tests van specifieke functies.
bovendien, omdat alle afhankelijkheden als invoer worden geleverd, kunnen we gemakkelijk afhankelijkheden mockeren. In een onzuivere omgeving, zouden we moeten bijhouden van de staat van een aantal wereldwijde afhankelijkheid gedurende alle tests.
echter, in een pure instelling, zouden we gewoon alle afhankelijkheden als invoer opgeven. We hoeven ons niet langer zorgen te maken over het handhaven van de Globale staat tijdens onze tests, en we kunnen nu mogelijk verschillende versies van afhankelijkheden leveren aan verschillende tests.
Hiermee kunnen we functies testen terwijl we expliciet controle hebben over de opgegeven afhankelijkheden in elke test.
referentiële transparantie
referentiële transparantie verwijst naar de mogelijkheid om de aanroep van een functie te vervangen door de bijbehorende uitvoerwaarde zonder het gedrag van een programma te veranderen.
om referentiële transparantie te bereiken, moet een functie zuiver zijn. Dit heeft voordelen in termen van leesbaarheid en snelheid. Compilers zijn vaak in staat om code te optimaliseren die referentiële transparantie vertoont.
Caching
omdat pure functies altijd dezelfde uitvoer retourneren voor dezelfde invoer, kunnen we de resultaten van pure functie aanroepen cachen.
Caching verwijst naar het gebruik van een techniek, zoals memoisatie, om de resultaten van functies op te slaan, zodat we ze slechts één keer hoeven te berekenen.
voor een functie f: Input -> Output
wordt dit meestal bereikt door middel van een map (zoals een hash-map) van Input -> Output
.
bij het uitvoeren van een functie controleren we eerst of de kaart de invoer als sleutel bevat. Als dit het geval is, retourneren we de uitvoerwaarde van de kaart, anders berekenen we f(input)
, en slaan we de uitvoer op in de kaart voordat we deze retourneren.