Accumulator Pattern
Convert to tail-recursive.
Accumulator Pattern is a free Scala for Backend Engineering & Functional Programming lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Scala for Backend Engineering & Functional Programming learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The Accumulator Pattern
The accumulator pattern converts a non-tail-recursive function into a tail-recursive one. You carry the partial result in an extra parameter (the accumulator) instead of building it up after the call returns.
The Core Idea
Instead of n + sum(n-1) (work after the call), you compute the new partial total before the call: sum(n-1, acc + n). Now the recursive call is the last action.
Before: Non-Tail Sum
This direct version is not tail-recursive: the addition waits for the recursive call.
object Main {
def sum(n: Int): Int =
if (n == 0) 0 else n + sum(n - 1)
def main(args: Array[String]): Unit = {
println(sum(50))
}
}After: Tail Sum with Accumulator
Add an acc parameter that holds the running total. The recursive call is now in tail position and can be optimized.
import scala.annotation.tailrec
object Main {
@tailrec
def sum(n: Int, acc: Int = 0): Int =
if (n == 0) acc else sum(n - 1, acc + n)
def main(args: Array[String]): Unit = {
println(sum(50))
}
}Tail-Recursive Factorial
Apply the same transformation to factorial: multiply into the accumulator before recursing.
import scala.annotation.tailrec
object Main {
@tailrec
def factorial(n: Int, acc: Long = 1): Long =
if (n <= 1) acc else factorial(n - 1, acc * n)
def main(args: Array[String]): Unit = {
println(factorial(10))
}
}Hiding the Accumulator
The extra parameter is an implementation detail. Wrap the tail-recursive worker in a clean public function so callers do not see acc.
import scala.annotation.tailrec
object Main {
def factorial(n: Int): Long = {
@tailrec
def loop(m: Int, acc: Long): Long =
if (m <= 1) acc else loop(m - 1, acc * m)
loop(n, 1)
}
def main(args: Array[String]): Unit = {
println(factorial(6))
}
}Accumulating a List
The pattern also builds collections. A tail-recursive reverse prepends each head to the accumulator list.
import scala.annotation.tailrec
object Main {
def reverse[A](xs: List[A]): List[A] = {
@tailrec
def loop(rem: List[A], acc: List[A]): List[A] = rem match {
case Nil => acc
case h :: t => loop(t, h :: acc)
}
loop(xs, Nil)
}
def main(args: Array[String]): Unit = {
println(reverse(List(1, 2, 3, 4)))
}
}Order of Accumulation
Note that prepending to the accumulator naturally reverses order. For a list-building function that preserves order, you often build reversed and reverse at the end, or use an efficient append structure.
Tail-Recursive map
Build a result list with an accumulator, then reverse once at the end to restore order.
import scala.annotation.tailrec
object Main {
def mapTail[A, B](xs: List[A])(f: A => B): List[B] = {
@tailrec
def loop(rem: List[A], acc: List[B]): List[B] = rem match {
case Nil => acc.reverse
case h :: t => loop(t, f(h) :: acc)
}
loop(xs, Nil)
}
def main(args: Array[String]): Unit = {
println(mapTail(List(1, 2, 3))(_ * 10))
}
}Relation to foldLeft
The accumulator pattern is exactly what foldLeft generalizes: it threads an accumulator through a collection tail-recursively. Many manual accumulator functions can be rewritten as a single foldLeft.
@main def run(): Unit = {
val total = List(1, 2, 3, 4).foldLeft(0)(_ + _)
println(total)
}When to Use It
Reach for the accumulator pattern when a recursive function processes a large linear structure and would otherwise overflow the stack. It trades a slightly less obvious shape for guaranteed stack safety.
Quick Check
Test your grasp of the accumulator pattern.
Recap
You learned the accumulator pattern:
- Carry the partial result in an extra parameter.
- Compute it before recursing to reach tail position.
- Hide the accumulator behind a clean public function.
- It generalizes to
foldLeft.
Frequently asked questions
Is the “Accumulator Pattern” lesson free?
Yes — the full text of “Accumulator Pattern” is free to read here on the web, and the Scala for Backend Engineering & Functional Programming course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Scala for Backend Engineering & Functional Programming course, upgrade to CoddyKit PRO.
What will I learn in “Accumulator Pattern”?
Convert to tail-recursive. You practise Scala for Backend Engineering & Functional Programming with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Scala for Backend Engineering & Functional Programming?
No prior experience is required. Scala for Backend Engineering & Functional Programming on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Accumulator Pattern” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Scala for Backend Engineering & Functional Programming lesson?
Yes. Every Scala for Backend Engineering & Functional Programming lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Recursion Basics
- The tailrec Annotation
- Accumulator Pattern
- Trampolining