Recursive call is not a tail call

Viewed 324

When I present it with the following code (first line of function commented out because while it would be necessary for correctness, I want to make sure it's not what's causing the problem here), the Kotlin compiler tells me the recursive call is not a tail call.

class Env(val global: Map<Symbol, Term>, val outer: Env?, val local: Array<Term?>) {
  tailrec operator fun get(i: Int): Term {
    // if (i < local.size) return local[i]!!
    val o = outer!!
    return o[i - local.size]
  }
}

If I change the syntax of the last line to explicitly say o.get(i - local.size) instead of using operator overloading, it makes no difference. Ditto if I uncomment the first line.

I cannot for the life of me see how it fails to be a tail call. Maybe I've just been staring at it so long I'm overlooking the obvious. Can anyone see what I'm doing wrong?

Update: If I rewrite it to take the object parameter explicitly instead of implicitly, the compiler is happy. Compiler bug?

tailrec fun get(env: Env, i: Int): Term {
  if (i < env.local.size) return env.local[i]!!
  val o = env.outer!!
  return get(env, i - env.local.size)
}
0 Answers
Related