Go Recursion

Recursion happens when a function calls itself. Each call works on a smaller version of the same problem until it reaches a simple base case that stops the chain. Recursion is a powerful technique for problems that naturally break into repeated sub-problems.

The Two Rules of Recursion

Every recursive function needs:

1. Base Case  ─── the condition that stops the recursion
2. Recursive Case ─── the call to itself with a smaller input

Without a base case, the function calls itself forever and crashes with a stack overflow.

Example – Factorial

Factorial of a number is the product of all integers from 1 to that number. Factorial of 5 = 5 × 4 × 3 × 2 × 1 = 120.

package main

import "fmt"

func factorial(n int) int {
    if n == 0 {         // base case
        return 1
    }
    return n * factorial(n-1) // recursive case
}

func main() {
    fmt.Println(factorial(5)) // 120
    fmt.Println(factorial(3)) // 6
}

Call Stack Diagram for factorial(4)

factorial(4)
  └── 4 * factorial(3)
            └── 3 * factorial(2)
                      └── 2 * factorial(1)
                                └── 1 * factorial(0)
                                          └── returns 1  ← base case

Unwinding:
factorial(0) = 1
factorial(1) = 1 * 1 = 1
factorial(2) = 2 * 1 = 2
factorial(3) = 3 * 2 = 6
factorial(4) = 4 * 6 = 24

Example – Fibonacci Sequence

The Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13… Each number is the sum of the two before it.

package main

import "fmt"

func fibonacci(n int) int {
    if n <= 1 {              // base case
        return n
    }
    return fibonacci(n-1) + fibonacci(n-2) // recursive case
}

func main() {
    for i := 0; i <= 7; i++ {
        fmt.Printf("fibonacci(%d) = %d\n", i, fibonacci(i))
    }
}

Output:

fibonacci(0) = 0
fibonacci(1) = 1
fibonacci(2) = 1
fibonacci(3) = 2
fibonacci(4) = 3
fibonacci(5) = 5
fibonacci(6) = 8
fibonacci(7) = 13

Example – Countdown

package main

import "fmt"

func countdown(n int) {
    if n == 0 {           // base case
        fmt.Println("Go!")
        return
    }
    fmt.Println(n)
    countdown(n - 1)      // recursive case
}

func main() {
    countdown(5)
}

Output:

5
4
3
2
1
Go!

Recursion vs Loop

FeatureRecursionLoop
Code styleElegant for tree/nested problemsStraightforward for simple counts
Memory useUses call stack — higher memoryLower memory
RiskStack overflow if base case is missingInfinite loop if condition never false
Best forTrees, graphs, divide-and-conquerCounting, iterating over collections

Key Points

  • A recursive function must have a base case to stop calling itself
  • Each recursive call should work on a smaller input toward the base case
  • Recursion uses the call stack — deep recursion can cause a stack overflow
  • Use recursion for problems like trees, nested structures, and divide-and-conquer algorithms
  • Loops are more memory-efficient for simple repeated tasks

Leave a Comment