Invoering
Functioneel programmeren is een programmeerparadigma waarin we alles proberen te binden in pure wiskundige functiestijl. Het is een declaratieve programmeerstijl. De nadruk ligt vooral op wat moet worden opgelost, in tegenstelling tot een imperatieve stijl waarbij de nadruk vooral ligt op hoe op te lossen. Er worden uitdrukkingen gebruikt in plaats van uitspraken. Een expressie wordt geëvalueerd om een waarde te produceren, terwijl een instructie wordt uitgevoerd om variabelen toe te wijzen. Deze functies hebben enkele speciale kenmerken die hieronder worden besproken.
Functioneel programmeren is gebaseerd op Lambda Calculus:
Lambda-calculus is een raamwerk ontwikkeld door Alonzo Church om berekeningen met functies te bestuderen. Het kan de kleinste programmeertaal ter wereld worden genoemd. Het geeft de definitie van wat berekenbaar is. Alles wat met lambda-calculus kan worden berekend, is berekenbaar. Het is qua rekenvermogen gelijk aan de Turing-machine. Het biedt een theoretisch raamwerk voor het beschrijven van functies en hun evaluatie. Het vormt de basis van vrijwel alle huidige functionele programmeertalen.
Feit: Alan Turing was een student van de Alonzo Church die de Turing-machine creëerde die de basis legde voor de imperatieve programmeerstijl.
Programmeertalen die functioneel programmeren ondersteunen: Haskell, JavaScript, Python, Scala, Erlang, Lisp, ML, Clojure, OCaml, Common Lisp, Racket.
Concepten van functioneel programmeren:
- Zuivere functies
- Herhaling Referentiële transparantie Functies zijn eersteklas en kunnen van hogere orde zijn. Variabelen zijn onveranderlijk
Zuivere functies: Deze functies hebben twee hoofdeigenschappen. Ten eerste produceren ze altijd dezelfde uitvoer voor dezelfde argumenten, ongeacht iets anders.
Ten tweede hebben ze geen bijwerkingen, dat wil zeggen dat ze geen argumenten, lokale/globale variabelen of invoer-/uitvoerstromen wijzigen.
Latere eigendommen worden onveranderlijkheid genoemd. Het enige resultaat van de pure functie is de waarde die deze retourneert. Ze zijn deterministisch.
Programma's die zijn uitgevoerd met behulp van functioneel programmeren zijn eenvoudig te debuggen omdat pure functies geen bijwerkingen of verborgen I/O hebben. Pure functies maken het ook eenvoudiger om parallelle/gelijktijdige applicaties te schrijven. Wanneer de code in deze stijl wordt geschreven, kan een slimme compiler veel dingen doen: hij kan de instructies parallelliseren, wachten met het evalueren van resultaten wanneer deze nodig zijn, en de resultaten onthouden, aangezien de resultaten nooit veranderen zolang de invoer niet verandert.
voorbeeld van de pure functie:
sum(x, y) // sum is function taking x and y as arguments return x + y // sum is returning sum of x and y without changing them>
Herhaling: Er is geen for- of while-lus in functionele talen. Iteratie in functionele talen wordt geïmplementeerd via recursie. Recursieve functies roepen zichzelf herhaaldelijk aan, totdat ze het basisscenario bereiken.
voorbeeld van de recursieve functie:
fib(n) if (n <= 1) return 1; else return fib(n - 1) + fib(n - 2);>
Referentiële transparantie: In functionele programma's veranderen variabelen die eenmaal zijn gedefinieerd hun waarde niet gedurende het hele programma. Functionele programma's hebben geen toewijzingsinstructies. Als we een bepaalde waarde moeten opslaan, definiëren we in plaats daarvan nieuwe variabelen. Dit elimineert alle kansen op bijwerkingen, omdat elke variabele op elk moment van uitvoering kan worden vervangen door de werkelijke waarde. De toestand van elke variabele is op elk moment constant.
k-nn-algoritme
Voorbeeld:
x = x + 1 // this changes the value assigned to the variable x. // So the expression is not referentially transparent.>
Functies zijn eersteklas en kunnen van hogere orde zijn: Eersteklasfuncties worden behandeld als eersteklasvariabelen. De eerste klas variabelen kunnen als parameter aan functies worden doorgegeven, kunnen worden geretourneerd uit functies of worden opgeslagen in datastructuren. Functies van hogere orde zijn de functies die andere functies als argumenten gebruiken en ze kunnen ook functies retourneren.
Voorbeeld:
show_output(f) // function show_output is declared taking argument f // which are another function f(); // calling passed function print_gfg() // declaring another function print('hello gfg'); show_output(print_gfg) // passing function in another function> Variabelen zijn onveranderlijk: Bij functioneel programmeren kunnen we een variabele niet wijzigen nadat deze is geïnitialiseerd. We kunnen nieuwe variabelen maken, maar we kunnen bestaande variabelen niet wijzigen, en dit helpt echt om de status gedurende de looptijd van een programma te behouden. Zodra we een variabele hebben gemaakt en de waarde ervan hebben ingesteld, kunnen we er volledig op vertrouwen dat de waarde van die variabele nooit zal veranderen.
Voor- en nadelen van functioneel programmeren
Voordelen:
- Pure functies zijn gemakkelijker te begrijpen omdat ze geen enkele status veranderen en alleen afhankelijk zijn van de input die eraan wordt gegeven. Welke output ze ook produceren, het is de retourwaarde die ze opleveren. Hun functiehandtekening geeft alle informatie over hen, dat wil zeggen hun retourtype en hun argumenten.
- Het vermogen van functionele programmeertalen om functies als waarden te behandelen en deze als parameters aan functies door te geven, maakt de code leesbaarder en gemakkelijker te begrijpen.
- Testen en debuggen is eenvoudiger. Omdat pure functies alleen argumenten aannemen en uitvoer produceren, produceren ze geen wijzigingen, ze nemen geen invoer of produceren geen verborgen uitvoer. Ze gebruiken onveranderlijke waarden, dus het wordt gemakkelijker om sommige problemen te controleren in programma's die geschreven zijn met pure functies.
- Het wordt gebruikt om gelijktijdigheid/parallelisme te implementeren, omdat pure functies geen variabelen of andere gegevens daarbuiten veranderen.
- Het maakt gebruik van een luie evaluatie die herhaalde evaluatie vermijdt, omdat de waarde alleen wordt geëvalueerd en opgeslagen wanneer deze nodig is.
Nadelen:
- Soms kan het schrijven van pure functies de leesbaarheid van code verminderen.
- Het schrijven van programma's in recursieve stijl in plaats van het gebruik van loops kan een beetje intimiderend zijn.
- Het schrijven van pure functies is eenvoudig, maar het combineren ervan met de rest van de applicatie en I/O-bewerkingen is een moeilijke taak.
- Onveranderlijke waarden en recursie kunnen leiden tot prestatievermindering.
Toepassingen:
tekenreeks naar int
- Het wordt gebruikt bij wiskundige berekeningen.
- Het is nodig waar gelijktijdigheid of parallellisme vereist is.
Feit: WhatsApp heeft voor zijn 900M slechts 50 ingenieurs nodig gebruikers omdat Erlang wordt gebruikt om zijn gelijktijdigheidsbehoeften te implementeren. Facebook gebruikt Haskell in zijn antispamsysteem.