Source

scala-robustness-brevity-ftw-talk / recursion.scala

Full commit
def fibonacci(n: Int): List[Int] = {
    def fibonacci(n: Int, l:List[Int],last: Int, secondLast: Int): List[Int] = {
        if (n == 0) {
            l
        } else {
            val sum = last + secondLast
            fibonacci(n-1, sum :: l, sum, last)
        } 
    }
    fibonacci(n-2,List(1,0),1,0) reverse
}

println(fibonacci(15))

// We deliberately introduce a buggy version
// which throws an exception when the countdown reaches 3

def fibonacci2(n: Int): List[Int] = {
    def fibonacci2(n: Int, l:List[Int],last: Int, secondLast: Int): List[Int] = {
        if (n == 0) {
            l
        } else if (n == 3) {
            throw new Exception
        } else {
            val sum = last + secondLast
            fibonacci2(n-1, sum :: l, sum, last)
        } 
    }
    fibonacci2(n-2,List(1,0),1,0) reverse
}

// Note the stack trace
// You would've expected many fibonacci2 methods there
// but will see only two. Thats tail call optimisation
println(fibonacci2(15))

// Note: JVM does not support tail call optimisation
// Scala compiler instead detects the situation and replaces
// it with a loop when it can