Elixir en Phoenix: schaalbare backendontwikkeling · Les

Recursie en functies van hogere orde

Begrijp recursie als fundamenteel functioneel concept en ontdek functies van hogere orde om gedrag te abstraheren.

Les 3 van 412 stappen

Recursie en functies van hogere orde is een gratis Elixir en Phoenix: schaalbare backendontwikkeling-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Elixir en Phoenix: schaalbare backendontwikkeling. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Elixir en Phoenix: schaalbare backendontwikkeling bevat in totaal 4 lessen.

Maak kennis met recursie in Elixir

Welkom bij recursie! In functioneel programmeren is recursie een krachtige techniek waarbij een functie zichzelf aanroept om een probleem op te lossen.

In plaats van lussen te gebruiken (zoals for of while in andere talen), gebruikt Elixir vaak recursie om over gegevens te itereren of acties te herhalen. Dit is een kernconcept dat je vaak zult gebruiken!

De twee pijlers van recursie

Elke recursieve functie heeft twee hoofdonderdelen nodig om correct te werken:

  • Basisgeval: Dit is de stopvoorwaarde. Deze bepaalt wanneer de functie moet stoppen met zichzelf aanroepen en een rechtstreeks resultaat moet retourneren. Zonder dit geval zou je functie oneindig blijven uitvoeren!
  • Recursieve stap: Hier roept de functie zichzelf opnieuw aan, maar met een kleinere of eenvoudigere versie van het oorspronkelijke probleem. Elke aanroep komt dichter bij het basisgeval.

Recursie in actie: faculteit

Laten we recursie bekijken aan de hand van een klassiek voorbeeld: de faculteit van een getal berekenen. De faculteit van n (geschreven als n!) is het product van alle positieve gehele getallen die kleiner dan of gelijk zijn aan n. Bijvoorbeeld: 5! = 5 * 4 * 3 * 2 * 1 = 120.

Let erop hoe factorial(n) factorial(n - 1) aanroept totdat het basisgeval 0 wordt bereikt.

defmodule Math do
  def factorial(0), do: 1
  def factorial(n) when n > 0, do: n * factorial(n - 1)
end

IO.puts "Factorial of 5: #{Math.factorial(5)}"

Efficiënte recursie: staartaanroepen

Hoewel recursie geweldig is, kan naïeve recursie soms leiden tot prestatieproblemen of een 'stack overflow' bij zeer diepe aanroepen.

Elixir (en de Erlang-VM) biedt optimalisatie van staartaanroepen (TCO). Als de recursieve aanroep de allerlaatste bewerking in een functie is, kan de VM deze optimaliseren en voorkomen dat er nieuwe stackframes worden aangemaakt. Hierdoor zijn staartrecursieve functies net zo efficiënt als lussen!

Optimaliseren met staartrecursie

Om TCO te bereiken, gebruiken we vaak een accumulator. Dit is een extra argument dat aan de functie wordt doorgegeven en het resultaat verzamelt naarmate de recursie vordert.

Vergelijk deze versie met de vorige. De recursieve aanroep factorial(n - 1, n * acc) is het laatste wat in de functie gebeurt, waardoor deze staartrecursief is.

defmodule Math do
  # Public interface, calls the private tail-recursive function
  def factorial(n), do: factorial(n, 1)

  # Private tail-recursive function with accumulator
  defp factorial(0, acc), do: acc
  defp factorial(n, acc) when n > 0, do: factorial(n - 1, n * acc)
end

IO.puts "Tail factorial of 5: #{Math.factorial(5)}"

Functies als eersteklaswaarden

Laten we nu functies van hogere orde (HOF's) bekijken. In Elixir zijn functies 'eersteklaswaarden'. Dit betekent dat je het volgende kunt doen:

  • Functies als argumenten aan andere functies doorgeven.
  • Functies als resultaten van andere functies retourneren.
  • Functies aan variabelen toewijzen.

Functies van hogere orde maken krachtige abstracties mogelijk, waardoor je code beknopter, flexibeler en herbruikbaarder wordt.

Lijsten transformeren met Enum.map

Enum.map/2 is een van de meest voorkomende functies van hogere orde. Deze neemt een opsombare verzameling (zoals een lijst) en een functie. De functie wordt op elk element toegepast en retourneert een nieuwe lijst met de getransformeerde elementen.

De oorspronkelijke lijst wordt nooit gewijzigd, in overeenstemming met de onveranderlijkheid van Elixir.

numbers = [1, 2, 3, 4]
doubled_numbers = Enum.map(numbers, fn n -> n * 2 end)

IO.puts "Original: #{inspect numbers}"
IO.puts "Doubled: #{inspect doubled_numbers}"

Lijsten filteren met Enum.filter

Een andere handige functie van hogere orde is Enum.filter/2. Deze neemt een opsombare verzameling en een functie die een booleaanse waarde (true of false) moet retourneren.

De functie retourneert een nieuwe lijst met alleen de elementen waarvoor de functie true retourneerde. Dit is ideaal om specifieke items uit een verzameling te selecteren.

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = Enum.filter(numbers, fn n -> rem(n, 2) == 0 end)

IO.puts "Original: #{inspect numbers}"
IO.puts "Even: #{inspect even_numbers}"

Samenvoegen met Enum.reduce

Enum.reduce/3 is misschien wel de krachtigste functie van hogere orde voor het werken met opsombare verzamelingen. Deze neemt een opsombare verzameling, een beginwaarde voor de accumulator en een functie.

De functie doorloopt de verzameling, past de functie toe op elk element en de huidige accumulator en reduceert uiteindelijk de hele verzameling tot één waarde.

numbers = [1, 2, 3, 4]
sum = Enum.reduce(numbers, 0, fn n, acc -> n + acc end)
product = Enum.reduce(numbers, 1, fn n, acc -> n * acc end)

IO.puts "Numbers: #{inspect numbers}"
IO.puts "Sum: #{sum}"
IO.puts "Product: #{product}"

Anonieme functies en functies van hogere orde

Je hebt fn n -> n * 2 end gezien. Dit zijn anonieme functies (of lambda's). Elixir biedt een verkorte notatie voor eenvoudige anonieme functies:

  • &1 verwijst naar het eerste argument.
  • &2 verwijst naar het tweede argument, enzovoort.
  • &(&1 + &2) is gelijkwaardig aan fn a, b -> a + b end.

Hierdoor worden aanroepen van functies van hogere orde nog beknopter!

numbers = [1, 2, 3, 4]
doubled_short = Enum.map(numbers, &(&1 * 2))
even_short = Enum.filter(numbers, &(rem(&1, 2) == 0))

IO.puts "Doubled (short): #{inspect doubled_short}"
IO.puts "Even (short): #{inspect even_short}"

Je kennis van functies van hogere orde testen

Functies van hogere orde vormen een hoeksteen van functioneel programmeren in Elixir. Laten we controleren of je het begrijpt.

Recursie en functies van hogere orde: belangrijkste punten

Goed gedaan! In deze les heb je twee fundamentele concepten van functioneel programmeren in Elixir begrepen:

  • Recursie: een functie die zichzelf aanroept en wordt bepaald door een basisgeval en een recursieve stap.
  • Optimalisatie van staartaanroepen (TCO): een belangrijke functie van Elixir voor efficiënte recursie zonder stackproblemen, vaak bereikt met een accumulator.
  • Functies van hogere orde (HOF's): functies die andere functies als argument nemen of retourneren, zoals Enum.map, Enum.filter en Enum.reduce.
  • Anonieme functies: beknopte manieren om functies inline te definiëren, vaak gebruikt met functies van hogere orde, waaronder de verkorte notatie &1.

Deze hulpmiddelen zijn essentieel voor het schrijven van expressieve en krachtige Elixir-code. Blijf oefenen!

Gratis beginnen

Leer Elixir met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
12
Lessen
48

Veelgestelde vragen

Is de les “Recursie en functies van hogere orde” gratis?

Ja — de volledige tekst van “Recursie en functies van hogere orde” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Elixir en Phoenix: schaalbare backendontwikkeling wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Elixir en Phoenix: schaalbare backendontwikkeling bevat in totaal 4 lessen.

Wat leer ik in “Recursie en functies van hogere orde”?

Begrijp recursie als fundamenteel functioneel concept en ontdek functies van hogere orde om gedrag te abstraheren. Je oefent met Elixir en Phoenix: schaalbare backendontwikkeling door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Elixir en Phoenix: schaalbare backendontwikkeling te beginnen?

Ervaring vooraf is niet nodig. Elixir en Phoenix: schaalbare backendontwikkeling op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Recursie en functies van hogere orde”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Elixir en Phoenix: schaalbare backendontwikkeling?

Ja. Elke les over Elixir en Phoenix: schaalbare backendontwikkeling bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Functies, modules en pipelining
  2. Werken met opsombare collecties
  3. Recursie en functies van hogere orde
  4. Lui evalueren met de Stream-module
← Terug naar Elixir en Phoenix: schaalbare backendontwikkeling