Search code examples
pythonscalarecursionactivation-record

Recursion in Python and Scala


Why does this Scala recursion

def foo(id:Int): Int = { 
    if (id == 0) { return id } else { foo(id - 1) }
}
foo(2)

returns 0, while this Python recursion returns None?

def foo(id):
    if id == 0:
        return id
    else:
        foo(id - 1)
foo(2)

In which way do Python and Scala handle recursion and manage nested activation records?


Solution

  • In Scala, any block is evaluated to the value of it's last statement. For example, you can write:

    val myVal = {
      val t = 1
      val r = 8
      t + r
    }
    

    Here, myVal would evaluated to 9.

    Similarly, your else block evaluates to the value returned from foo(id - 1) (even though there's no explicit return keyword), and therefore the value of the entire method body would evaluate to that value as long as the else block is reached (the entire if statement would be evaluated to the result of foo(id - 1), and since that if is the last (and only) statement in the method body - that would be the method's return value).

    You can drop the first return keyword as well:

    def foo(id:Int): Int = { 
      if (id == 0) id else foo(id - 1)
    }
    

    In Python, that's simply not the case; Only return statements signify the method's return value. If you return nothing, None is returned.