I am confused by following code: the code is artificial, but still I think it is tail recursive. The compiler does not agree and produces an error message:
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
None.getOrElse( return s )
}
listSize(l.tail, s + 1)
}
How is the code above making tail recusion not possible? Why is the compiler telling me:
could not optimize @tailrec annotated method listSize: it contains a recursive call not in tail position
A similar code (with return
inside of map
) compiles fine:
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
Some(()).map( return s )
}
listSize(l.tail, s + 1)
}
Even the code obtained by inlining None.isEmpty
compiles fine:
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
if (None.isEmpty) {
return s
} else None.get
}
listSize(l.tail, s + 1)
}
On the other hand, code with slightly modified map is rejected by the compiler and produces the error:
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
Some(()).map( x => return s )
}
listSize(l.tail, s + 1)
}