0Pricing
Scala for Backend Engineering & Functional Programming · Lesson

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

  1. Recursion Basics
  2. The tailrec Annotation
  3. Accumulator Pattern
  4. Trampolining
← Back to Scala for Backend Engineering & Functional Programming