De annotatie tailrec
Gegarandeerde optimalisatie
De annotatie tailrec is een gratis Scala voor backend-engineering en functioneel programmeren-les op CoddyKit. Dit is les 2 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 Scala voor backend-engineering en functioneel programmeren. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Scala voor backend-engineering en functioneel programmeren bevat in totaal 4 lessen.
Wat is staartrecursie
Een recursieve aanroep staat in de staartpositie wanneer dit de allerlaatste actie van de functie is. Een staartrecursieve functie kan worden geoptimaliseerd tot een lus die één stackframe hergebruikt en daardoor nooit overloopt.
Staartpositie
In n * factorial(n-1) is de recursieve aanroep niet de laatste actie: de vermenigvuldiging vindt plaats nadat de aanroep terugkeert. In gcd(b, a % b) is de aanroep wel de laatste actie. Alleen de tweede functie is staartrecursief.
De annotatie @tailrec
Importeer scala.annotation.tailrec en annoteer een methode. De compiler controleert dan of de aanroep echt in de staartpositie staat en past de optimalisatie toe. Als dat niet zo is, mislukt het compileren.
import scala.annotation.tailrec
object Main {
@tailrec
def countdown(n: Int): Unit = {
if (n >= 0) {
println(n)
countdown(n - 1)
}
}
def main(args: Array[String]): Unit = countdown(3)
}Gegarandeerde optimalisatie
Het belangrijkste voordeel van @tailrec is de garantie tijdens het compileren. Je krijgt meteen te horen dat je functie niet stackveilig is, in plaats van dit pas te ontdekken door een crash tijdens uitvoering met grote invoer.
Een staartrecursieve gcd
Het algoritme van Euclides is al staartrecursief: de recursieve aanroep vormt het volledige resultaat van de funct body. Door de annotatie toe te voegen bevestig je dit.
import scala.annotation.tailrec
object Main {
@tailrec
def gcd(a: Int, b: Int): Int =
if (b == 0) a else gcd(b, a % b)
def main(args: Array[String]): Unit = {
println(gcd(1071, 462))
}
}Wat de staartpositie doorbreekt
Veelvoorkomende patronen die de aanroep uit de staartpositie halen:
- Rekenen met het resultaat:
n + f(...). - Inpakken in een constructor:
x :: f(...). - Het resultaat gebruiken in een
try-blok.
Niet-staartrecursief voorbeeld
Deze som is niet staartrecursief, omdat de optelling de aanroep omhult. Als je er @tailrec aan toevoegt, ontstaat een compileerfout. (De annotatie is weggelaten zodat het voorbeeld werkt.)
object Main {
def sum(n: Int): Int =
if (n == 0) 0
else n + sum(n - 1)
def main(args: Array[String]): Unit = {
println(sum(100))
}
}Waarom optimalisatie niet mogelijk is
Omdat n + sum(n - 1) n moet onthouden om de optelling af te ronden nadat de aanroep terugkeert, heeft elk niveau zijn eigen stackframe nodig. De compiler kan dit niet tot een lus samenvouwen, dus de functie is niet staartrecursief.
Een grote staartrecursieve lus
Een staartrecursieve som met een accumulator werkt voor enorme invoer zonder over te lopen, omdat één frame wordt hergebruikt.
import scala.annotation.tailrec
object Main {
@tailrec
def sumTo(n: Int, acc: Long = 0): Long =
if (n == 0) acc else sumTo(n - 1, acc + n)
def main(args: Array[String]): Unit = {
println(sumTo(1000000))
}
}tailrec vereist final of lokaal
Om @tailrec te kunnen gebruiken, mag de methode niet overschrijfbaar zijn: de methode moet private, final of lokaal/genest zijn. Een open methode kan worden overschreven, waardoor de optimalisatie niet gegarandeerd is; daarom weigert de compiler deze.
Kanttekening bij wederzijdse recursie
@tailrec optimaliseert alleen een functie die zichzelf aanroept. Twee functies die elkaar aanroepen (wederzijdse recursie) kunnen niet rechtstreeks door de JVM worden geoptimaliseerd voor staartrecursie; daarvoor heb je trampolines nodig, die later aan bod komen.
Korte toets
Toets je begrip van @tailrec.
Samenvatting
Je hebt de annotatie @tailrec geleerd:
- Een aanroep in de staartpositie kan worden geoptimaliseerd tot een lus.
@tailrecgeeft tijdens het compileren een garantie op stackveiligheid.- De methode moet
final,privateof lokaal zijn. - De annotatie geldt alleen voor zelfrecursie, niet voor wederzijdse recursie.
Leer Scala 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
- 39
- Lessen
- 143
Veelgestelde vragen
Is de les “De annotatie tailrec” gratis?
Ja — de volledige tekst van “De annotatie tailrec” 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 Scala voor backend-engineering en functioneel programmeren wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Scala voor backend-engineering en functioneel programmeren bevat in totaal 4 lessen.
Wat leer ik in “De annotatie tailrec”?
Gegarandeerde optimalisatie Je oefent met Scala voor backend-engineering en functioneel programmeren 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 Scala voor backend-engineering en functioneel programmeren te beginnen?
Ervaring vooraf is niet nodig. Scala voor backend-engineering en functioneel programmeren 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 2 van 4.
Hoe lang duurt de les “De annotatie tailrec”?
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 Scala voor backend-engineering en functioneel programmeren?
Ja. Elke les over Scala voor backend-engineering en functioneel programmeren 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
- De basis van recursie
- De annotatie tailrec
- Accumulatorpatroon
- Trampolining