# Qualified return from lambda

**URL:** https://discuss.kotlinlang.org/t/qualified-return-from-lambda/16135
**Category:** Language Design
**Created:** [January 30, 2020, 4:25pm UTC](https://discuss.kotlinlang.org/t/qualified-return-from-lambda/16135 "2020-01-30T16:25:54Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![stenlee](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/stenlee/32/6623_2.png) [@stenlee](https://discuss.kotlinlang.org/u/stenlee)
#### Post date: [January 30, 2020, 4:25pm UTC](https://discuss.kotlinlang.org/t/qualified-return-from-lambda/16135/1 "2020-01-30T16:25:54Z")

</div>

Consider the following (android) code snippet, and more specifically the qualified return from the lambda

```kotlin
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<Button>(R.id.done_button).setOnClickListener { done_btn ->
            val nn_edit = findViewById<EditText>(R.id.nickname_edit)
            if (nn_edit.text.isBlank())
                return@setOnClickListener

            // do something meaningful if edit content is not blank
        }
    }

```

I just (briefly) read this [https://kotlinlang.org/docs/reference/returns.html](https://kotlinlang.org/docs/reference/returns.html)  
And either I’ve missed something, or I have an objection to this construct in general.  
You see, it makes sense in the `forEach` examples in the above docs.  
Because in that case the `forEach` not only _lexically_ encloses the lambda, but also _executionally_ encloses it, i.e. while the lambda executes (possibly multiple times) there is an active `forEach` invocation down the stack, so it makes sense to `return` to it.

But in the above example with `setOnClickListener { ... }` this is not the case – the `setOnClickListener` only lexically encloses the lambda so where the heck the lambda is returning to (at execution time, I mean) ?

---

<div class="post-metadata">

### Author: ![al3c](https://avatars.discourse-cdn.com/v4/letter/a/e47774/32.png) [@al3c](https://discuss.kotlinlang.org/u/al3c)
#### Post date: [January 30, 2020, 4:44pm UTC](https://discuss.kotlinlang.org/t/qualified-return-from-lambda/16135/3 "2020-01-30T16:44:07Z")

</div>

Sorry, what does the objection consist of exactly?

In case you missed that, you don’t have to specify a label to return to, `return` will just return from the innermost lambda you’re in, in this case `return` is equivalent to `return@setOnClickListener`.

You really have a choice of where to return to in case of inline functions, and `setOnClickListener` come from Java, hence it’s not `inline`

---

<div class="post-metadata">

### Author: ![stenlee](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/stenlee/32/6623_2.png) [@stenlee](https://discuss.kotlinlang.org/u/stenlee)
#### Post date: [January 30, 2020, 7:58pm UTC](https://discuss.kotlinlang.org/t/qualified-return-from-lambda/16135/4 "2020-01-30T19:58:01Z")

</div>

> [@al3c](#):
>
> in this case `return` is equivalent to `return@setOnClickListener` .

Negative, it is not.  
In this case `return` results in  
`'return' is not allowed here` (compiler error)

The doc says (quote):

 ![image](https://us1.discourse-cdn.com/flex019/uploads/kotlinlang/original/2X/b/ba22a0c6300b17eff3b0d3947ef8b3bc168c5731.png)  
As you pointed out `setOnClickListener` comes from Java hence the return in this case must be qualified.  
My problem is `return@setOnClickListener` somehow suggests to me (as a human being or as a programmer - you name it) that as a result of this return, execution will be passed _back_ to `setOnClickListener` but _it won’t_.

I’d be cool with using a non-implicit return label here:

```kotlin
findViewById<Button>(R.id.done_button).setOnClickListener clickHandler@{ done_btn ->
            val nn_edit = findViewById<EditText>(R.id.nickname_edit)
            if (nn_edit.text.isBlank())
                return@clickHandler

```

To me this is a language usability/UX issue.

Another usability issue is - at the call site, how am I supposed to make a distinction between an inline and non inline function? That is, without using a capable IDE that will show me the declaration of a function when I do Ctrl+hover it? After all, when doing code reviews in Github that sweet on-the-fly inspection is not available.

---

<div class="post-metadata">

### Author: ![HughG](https://avatars.discourse-cdn.com/v4/letter/h/35a633/32.png) [@HughG](https://discuss.kotlinlang.org/u/HughG)
#### Post date: [January 30, 2020, 8:35pm UTC](https://discuss.kotlinlang.org/t/qualified-return-from-lambda/16135/5 "2020-01-30T20:35:56Z")

</div>

> [@stenlee](#):
>
> My problem is `return@setOnClickListener` somehow suggests to me (as a human being or as a programmer - you name it)

I take your point but it may just be something you have to get used to. When learning a new language I find there are some things which annoy me for ages, and some I come to live with. This one never confused me, though.

> [@stenlee](#):
>
> at the call site, how am I supposed to make a distinction between an inline and non inline function? That is, without using a capable IDE

You can’t, but the code won’t compile if you do the wrong thing, and a first step before a code review should be, “does it even compile?”.

There was another thread recently about someone getting confused by an unlabeled return, thinking it would return from the innermost inline function call. But again, I never found that confusing: an unlabeled return always returns from the innermost function _definition_.

---

<div class="post-metadata">

### Author: ![al3c](https://avatars.discourse-cdn.com/v4/letter/a/e47774/32.png) [@al3c](https://discuss.kotlinlang.org/u/al3c)
#### Post date: [January 31, 2020, 10:25am UTC](https://discuss.kotlinlang.org/t/qualified-return-from-lambda/16135/6 "2020-01-31T10:25:46Z")

</div>

whoops sorry ☹

---

<div class="post-metadata">

### Author: ![alexis.manin](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/alexis.manin/32/8381_2.png) [@alexis.manin](https://discuss.kotlinlang.org/u/alexis.manin)
#### Post date: [January 31, 2020, 1:37pm UTC](https://discuss.kotlinlang.org/t/qualified-return-from-lambda/16135/7 "2020-01-31T13:37:00Z")

</div>

I think that Kotlin provide something similar to your need : [local functions](https://kotlinlang.org/docs/reference/functions.html#local-functions).

We could rewrite your example with something like this :

```nohighlight
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        fun handleClick(target : View) {
            val nn_edit = findViewById<EditText>(R.id.nickname_edit)
            if (nn_edit.text.isBlank())
                return

            // do something meaningful if edit content is not blank
        }

        findViewById<Button>(R.id.done_button).setOnClickListener {done_btn -> handleClick(btn) }
    }

```

Personally, I’d rather create a member function, but local ones can help when both local variable access and clear logic separation is needed.

Here is a trivial (and totally useless) example of local function that you can execute in a REPL 🙂

```nohighlight
fun printDivision(numerator : Int, denominator : Int) {
    
    fun divideSafely() { 
        if (denominator == 0) {
            println("Cowardly refusing to divide by zero")
            return
        }
        
        println("$numerator / $denominator = ${numerator / denominator}")
    } 
    
    divideSafely()
}

printDivision(2, 0)
println(" -- ")
printDivision(4, 2)

```

Hope it helps,
