Vad är en ren funktion?
fördelar
det finns flera fördelar med att använda rena funktioner, både vad gäller prestanda och användbarhet.
läsbarhet
rena funktioner är mycket lättare att läsa och resonera om. Alla relevanta ingångar och beroenden tillhandahålls som parametrar, så inga effekter observeras som ändrar variabler utanför uppsättningen ingångar.
detta innebär att vi snabbt kan förstå en funktion och dess beroenden, bara genom att läsa funktionens deklaration. Så om en funktion deklareras som f(a, b, c)
då vet vi att endast a
b
och c
är beroenden av f
.
portabilitet
eftersom alla beroenden tillhandahålls som inmatningsparametrar och inte nås via ett globalt sammanhang kan dessa beroenden bytas ut beroende på i vilket sammanhang funktionen anropas.
detta innebär att samma funktion kan fungera på olika implementeringar av samma resurs, till exempel.
detta gör koden mycket mer bärbar och återanvändbar eftersom samma funktion kan användas i olika sammanhang, snarare än att behöva skriva en annan funktion bara för att använda en annan implementering av samma klass.
till exempel, istället för att behöva skriva två olika orena funktioner för att använda två olika loggers som lagras globalt, skulle en ren funktion bara ta in önskad logger som en ingång.
testning
bristen på biverkningar gör pure-funktioner mycket enkla att testa, eftersom vi bara behöver testa att ingångarna ger de önskade utgångarna. Vi behöver inte kontrollera giltigheten för något globalt programtillstånd i våra tester av specifika funktioner.
dessutom, eftersom alla beroenden tillhandahålls som ingångar, kan vi enkelt håna beroenden. I en oren miljö måste vi hålla reda på tillståndet för något globalt beroende under alla tester.
men i en ren inställning skulle vi helt enkelt tillhandahålla alla beroenden som inmatning. Vi behöver inte längre oroa oss för att upprätthålla det globala tillståndet under våra tester, och vi kan nu potentiellt tillhandahålla olika versioner av beroenden till olika tester.
detta gör att vi kan testa funktioner samtidigt som vi uttryckligen har kontroll över de angivna beroenden i varje test.
Referenstransparens
Referenstransparens avser att kunna ersätta en funktions anrop med motsvarande utgångsvärde utan att ändra beteendet hos ett program.
för att uppnå referenstransparens måste en funktion vara ren. Detta har fördelar när det gäller läsbarhet och hastighet. Kompilatorer kan ofta Optimera kod som uppvisar referenstransparens.
Caching
eftersom rena funktioner alltid returnerar samma utgång för samma ingång, kan vi cacha resultaten av rena funktionsanrop.
Caching avser att använda en teknik, såsom memoisering, för att lagra resultaten av funktioner så att vi bara behöver beräkna dem en gång.
typiskt för en funktion f: Input -> Output
detta åstadkommes genom en karta (t.ex. en hash-karta) från Input -> Output
.
När du utför en funktion kontrollerar vi först om kartan innehåller ingången som en nyckel. Om det gör det returnerar vi kartans utgångsvärde, annars beräknar vi f(input)
och lagrar sedan utmatningen på kartan innan den returneras.