Tail recursion inside lambda passed to inline higher order function

I like using tail recursive functions to replace some loops as it is often more straightforward. But one big limitation that I am chafing against is that I can’t use calls to higher order inline functions (e.g. let).

For example here is code to search an open addressed hash table:

tailrec fun findItem(key: Foo, index: Int = key.hashCode()): Foo?
{
    val entry = table[index % table.size]

    if(entry == null || entry.key == key)
    {
        return entry;
    }
    else
    {
        return find(key, index + 1)
    }
}

It would be nice to combine that function down to a single line using higher order function like let:

tailrec fun findItem(key: Foo, index: Int = key.hashCode()): Foo?
    = table[index % table.size]?.let { if(it.key == key) it else find(key, index + 1) }

But the compiler does not think it is a tail recursive call but because let is inlined it really is tail recursive.

Am I hoping for too much smarts in the compiler to handle a tail recursive call in a lambda passed to an inline higher order function?

2 Likes

I have encountered with same issue. Maybe it is worth to create issue on their issue tracker?