简体   繁体   中英

Kotlin recursion stack overflow

I have written this recursive function in Kotlin:

fun recursive(target: String, population: Population, debugFun: (String) -> Unit) : Population {
    if (population.solution(target).toString() == target) {
        return population
    }
    debugFun.invoke(population.solution(target).toString())
    return recursive(target, population.evolve(target), debugFun)
}

It will run an indeterminate amount of times (because I'm using randomness to converge on solution in evolutionary algorithm). I am frequently getting stack overflow. What is the maximum stack depth for Kotlin/JVM languages? Should i just write the function non recursively?

The tailrec keyword tells the Kotlin compiler to use tail recursion. It therefore unrolls the recursion into a loop and this way you get rid of the StackOverflowError .

tailrec fun recursive(target: String, population: Population, debugFun: (String) -> Unit) : Population {
    if (population.solution(target).toString() == target) {
        return population
    }
    debugFun.invoke(population.solution(target).toString())
    return recursive(target, population.evolve(target), debugFun)
}

So when using tailrec the compiler creates something which matches to following function:

fun recursive(target: String, population: Population, debugFun: (String) -> Unit) : Population{
    var tmp = population

    while (true) {
        if (tmp.solution(target).toString() == target) {
            return tmp
        }
        debugFun.invoke(population.solution(target).toString())
        tmp = tmp.evolve(target)
    }
}

In this function no method calls are made any more therefore nothing gets pushed to the stack and we are save from StackOverflowError .

Note that we can still run into an endless loop!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM