Browse Learn Clojure Foundations as a Java Developer

Recursion and Looping in Clojure

Replace Java-style index loops with sequence transformations, reduce, recursion, and loop/recur when explicit iterative state is the clearest tool.

Java developers often reach for for loops out of habit: indexes, mutable accumulators, and in-place updates. In Clojure, the default tools are different—most iteration becomes sequence transformation, and explicit looping is expressed with reduce or loop/recur.

This chapter shows you how to think in terms of data flow instead of control flow. When you do need a “real loop,” you will learn the Clojure primitives that make it explicit and safe, without hiding mutation behind clever tricks.

The goal is not to write recursive code everywhere; it is to stop fighting the language and choose the simplest iteration shape for the problem.

In this section

  • Recursion Basics for Java Developers
    Understand recursion as a problem-solving shape with a base case, a smaller recursive step, and clear trade-offs against loops and reduce.
    • Understanding Recursion in Clojure
      Learn how recursive Clojure functions use base cases and smaller steps, where they resemble Java recursion, and why loop/recur matters for stack safety.
    • Recursion vs Iteration in Clojure
      Compare recursion, Java-style iteration, reduce, and loop/recur so you can choose the clearest Clojure iteration shape for each problem.
  • Recursive Functions in Clojure
    Write recursive Clojure functions with obvious base cases, safe recursive steps, and clear stack trade-offs before reaching for loop/recur or reduce.
    • Writing Recursive Functions in Clojure
      Build recursive Clojure functions with base cases, smaller recursive steps, factorial and Fibonacci examples, and guidance for Java developers moving away from loop-first code.
    • Stack Safety for Recursive Functions
      Understand when recursive Clojure calls consume stack, when loop/recur can reuse a frame, and how to avoid stack overflow in Java-scale data work.
  • Tail Recursion with recur
    Use Clojure's explicit recur form for stack-safe tail-position loops, and understand when ordinary recursion, reduce, or sequence functions are clearer.
    • How Tail Recursion Works in Clojure
      Understand tail position, accumulator state, and why Clojure requires explicit recur instead of automatically optimizing ordinary recursive calls.
    • Using recur in Clojure
      Rewrite loop-shaped recursive code with loop/recur, accumulators, and tail-position updates that Java engineers can review for stack safety.
    • Limits of recur in Clojure
      Learn the two hard recur rules: it must be in tail position, and it can only target the nearest function or loop.
  • Replacing Java Loops in Clojure
    Translate Java loop habits into Clojure shapes: map and filter for element work, reduce for accumulation, loop/recur for custom state transitions, and direct recursion for recursive data.
    • Using loop and recur in Clojure
      Replace Java while-style loops with Clojure loop/recur when you need explicit state transitions, fixed local bindings, and stack-safe iteration.
    • When Recursive Loops Help in Clojure
      Learn when recursive loops make Clojure code clearer than Java-style mutation, and when reduce or direct sequence functions are the better replacement.
  • Lazy Sequences in Clojure
    Understand when Clojure sequence work is deferred, how lazy pipelines compose, and why infinite sequences are safe only when consumption is bounded.
    • How Lazy Sequences Work in Clojure
      Learn how Clojure lazy sequences defer work, compose transformations, and differ from Java iterators and streams in evaluation timing.
    • Creating Lazy Sequences in Clojure
      Create lazy sequences with lazy-seq, repeat, range, iterate, and sequence transformations while keeping realization and memory retention visible.
    • Infinite Sequences in Clojure
      Work with unbounded Clojure sequences safely by pairing lazy producers with bounded consumers such as take, take-while, and finite reductions.
  • The loop Construct in Clojure
    Write explicit local loops with loop/recur when an algorithm needs evolving bindings, early termination, or state transitions that are clearer than a pipeline or reduce.
    • Using loop and recur in Clojure
      Use loop to create a local recursion point and recur to update bindings without mutable Java-style loop variables or unbounded stack growth.
    • loop/recur Examples in Clojure
      Practice loop/recur with counters, accumulators, collection scans, and state transitions so Java loop patterns translate into clear Clojure code.
  • Recursion and Looping Examples
    Practice translating Java loops into Clojure pipelines, reduce calls, loop/recur forms, and recursive functions where each shape fits best.
  • Java Loops vs Clojure Recursion
    Compare Java loop habits with Clojure alternatives: sequence pipelines, reduce, loop/recur, and direct recursion when the data shape calls for it.
    • Java Loop Constructs and Clojure Equivalents
      Review how Java for, enhanced for, while, and do-while loops express counting, traversal, accumulation, and conditional repetition, then map each intent to idiomatic Clojure forms.
    • Translating Java Loops to Clojure
      Work through Java-to-Clojure loop translations for accumulation, filtering, early exit, indexed traversal, and recursive data so you choose the right Clojure construct instead of mechanically rewriting syntax.
    • Trade-Offs of Recursion and Loops
      Compare readability, stack safety, allocation, laziness, performance, and team maintainability when choosing between Java loops, Clojure sequence operations, loop/recur, and direct recursion.
  • When Recursion Helps in Clojure
    Choose between direct recursion, sequence pipelines, reduce, loop/recur, lazy sequences, and Java interop by matching the Clojure construct to the shape of the work.
    • Use Cases for Recursion in Clojure
      Learn where direct recursion is worth using in Clojure: recursive data structures, divide-and-conquer algorithms, parsers, graph traversal, and bounded structural transformations.
    • Alternatives to Recursion in Clojure
      Use sequence functions, reduce, transducers, lazy sequences, doseq, and loop/recur when they express a loop's intent better than direct recursion.
  • Recursion and Looping Practice
    Practice translating Java loops into Clojure sequence pipelines, reduce, loop/recur, lazy sequences, and direct recursion with stack-safety checkpoints and review prompts.
Revised on Saturday, May 23, 2026