Recursion
Functions in Luma can call themselves.
This is called recursion, and it is useful for working with lists, trees, mathematical definitions, and algorithms.
Basic Recursive Function
fn factorial(n: int) -> int {
if n <= 1 {
return 1
}
return n * factorial(n - 1)
}
print(factorial(5)) // 120Recursion with Optionals
fn find_first(nums: [int], target: int, index: int) -> ?int {
if index >= nums.len() {
return nil
}
if nums[index] == target {
return index
}
return find_first(nums, target, index + 1)
}
nums: [int] = [3, 4, 5, 6]
print(find_first(nums, 5, 0)) // 2Tail-Recursive Style (Planned Optimization)
Luma will initially compile recursion directly without optimization.
Support for tail recursion (where the last operation is the recursive call) is planned, but not guaranteed in the first versions.
Example of tail-recursive style:
fn sum_tail(nums: [int], index: int, acc: int) -> int {
if index >= nums.len() {
return acc
}
return sum_tail(nums, index + 1, acc + nums[index])
}This is safe but not yet guaranteed to optimize stack frames.
When to Prefer Iteration
Some problems read better when using loops or .walk():
fn sum(nums: [int]) -> int {
total: int = 0
nums.walk(x) -> total = total + x
return total
}Prefer iteration when:
- The algorithm is inherently linear
- Deep recursion could risk stack overflow
.walk()expresses it more clearly
Mutual Recursion
Luma supports functions calling each other:
fn is_even(n: int) -> bool {
if n == 0 { return true }
return is_odd(n - 1)
}
fn is_odd(n: int) -> bool {
if n == 0 { return false }
return is_even(n - 1)
}
print(is_even(10)) // trueGotchas
Infinite recursion
fn loop() -> int {
return loop() // ERROR: infinite recursion (runtime)
}Missing base case
Always ensure recursion eventually stops.
Stack depth limits
Recursive functions grow the call stack. Excessive recursion may cause runtime errors.
Last updated on