fcracker79
fcracker79

Reputation: 1218

Returning anonymous functions rather than lambda function

I cannot understand why the wrong function is illegal in Kotlin


fun right1() : (String) -> String {
    return {
        when {
            it.isEmpty() -> "Empty"
            else -> it.reversed()
        }
    }
}


fun wrong() : (String) -> String {
    return fun(s: String): String {
        when {
            s.isEmpty() -> "Empty"
            else -> s.reversed()
        }
    }
}

fun right2() : (String) -> String {
    return {
        s: String -> 
        when {
            s.isEmpty() -> "Empty"
            else -> s.reversed()
        }
    }
}

It seems to be that I can only return lambda functions and non anonymous ones.

Sorry for the trivial question, I am a Kotlin newbye.

Upvotes: 0

Views: 1533

Answers (2)

Willi Mentzel
Willi Mentzel

Reputation: 29844

First, let's examine why right1 and right2 are correct. Since you return a lambda and the lambda will return its last expression which is when it will work for right1 and right2.

Now, let's take a look at wrong. The compiler will give the following error.

A 'return' expression is required in a function with a block body.

So, all you have to do is add a return statement before when, like so:

fun notWrong() : (String) -> String {
    return fun(s: String): String {
        return when {
            s.isEmpty() -> "Empty"
            else -> s.reversed()
        }
    }
}

But there is a better way! Note, that you can take advantage of Kotlin's type inference like that:

fun notWrong() = { s: String -> // parameter of lambda is a String
    when { // String is inferred as return type of when expression
        s.isEmpty() -> "Empty"
        else -> s.reversed()
    }
}

This is less redundant and does the same thing: return a lambda which takes a String as parameter and returns a String.

Invoking the returned lambda will work like this:

notWrong()("Hello World")

The first pair of parenthesis are for the invocation of notWrong and the second for the invocation of the lambda.

Upvotes: 2

Sergio
Sergio

Reputation: 30655

You can return anonymous functions. Just add return statement before when and it will work:

fun wrong() : (String) -> String {
    return fun(s: String): String {
        return when {
            s.isEmpty() -> "Empty"
            else -> s.reversed()
        }
    }
}

And you can call it something like this:

wrong()("string")
// or using a variable:
val v = wrong()
v("string")

Upvotes: 1

Related Questions