# Chain invokes with lambda arguments

**URL:** <https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478>\
**Category:** Language Design\
**Created:** [April 18, 2024, 6:47am UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478 "2024-04-18T06:47:18Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![zergeone](https://avatars.discourse-cdn.com/v4/letter/z/96bed5/32.png) [@zergeone](https://discuss.kotlinlang.org/u/zergeone)\
**Post date:** [April 18, 2024, 6:47am UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/1 "2024-04-18T06:47:18Z")

</div>

Simplified code:

```kotlin
    object B {
        operator fun invoke(arg: () -> Unit) {}
    }
    object A {
        operator fun invoke(arg: () -> Unit) = B
    }
    fun f() {
        (A {}) {} // ok
        A {} {} // error "Only one lambda expression is allowed"
    }

```

Perhaps it would be more useful to interpret the second case the same way as the first one instead of generating an error?

---

<div class="post-metadata">

**Author:** ![joffrey.bion](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/joffrey.bion/32/5084_2.png) [@joffrey.bion](https://discuss.kotlinlang.org/u/joffrey.bion)\
**Post date:** [April 22, 2024, 8:54am UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/2 "2024-04-22T08:54:03Z")

</div>

What if there are 2 overloads, one of which taking 2 arguments?

Also, this is a quite contrived, oversimplified example. If the lambdas actually contain code, especially multi-line code, this is going to be quite confusing even in the case without overloads. I think neither option is nice in that case. You should rather prefer extracting the first call into a variable that you name with something that makes sense, and then call that variable as a function:

```kotlin
fun f() {
    val doTheThing = A { ... }
    doTheThing {
        ...
    }
}

```

---

<div class="post-metadata">

**Author:** ![zergeone](https://avatars.discourse-cdn.com/v4/letter/z/96bed5/32.png) [@zergeone](https://discuss.kotlinlang.org/u/zergeone)\
**Post date:** [April 22, 2024, 10:30am UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/3 "2024-04-22T10:30:50Z")

</div>

IMHO, main source or confusion is usage of `operator invoke` in regular code ))

But it’s very handy in various DSL’s, where someone may prefer `A { } { }` syntax.

> [@joffrey.bion](#):
>
> one of which taking 2 arguments?

two arguments must be separated with comma or `() {}` construction, not `{} {}`, how does this relate to this case?

upd: Finally i found a workaround without bracketing the first fragment, `A {}() {}` but it’s still ugly )

---

<div class="post-metadata">

**Author:** ![joffrey.bion](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/joffrey.bion/32/5084_2.png) [@joffrey.bion](https://discuss.kotlinlang.org/u/joffrey.bion)\
**Post date:** [April 22, 2024, 10:52am UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/4 "2024-04-22T10:52:25Z")

</div>

> two arguments must be separated with comma or `() {}` construction, not `{} {}` , how does this relate to this case?

Fair enough, my first point was moot.

However, my most important point is the second.

> But it’s very handy in various DSL’s, where someone may prefer `A { } { }` syntax

I don’t believe a DSL with 2 consecutive blocks is very readable (especially when their contents is multi-line, but even on one line) because it’s not very clear which lambda plays what role.

I think the best for such DSLs is to use an infix function instead of `invoke()` in order to keep the chain effect but provide names in between: `A { } something { }`. This solves the weirdness of having 2 blocks without clear semantics.

---

<div class="post-metadata">

**Author:** ![hg42](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/hg42/32/10351_2.png) [@hg42](https://discuss.kotlinlang.org/u/hg42)\
**Post date:** [April 25, 2024, 3:03pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/5 "2024-04-25T15:03:26Z")

</div>

I don’t agree, because

`x {} {}`

is basically the same syntax like

`x () ()`

---

<div class="post-metadata">

**Author:** ![tsp](https://avatars.discourse-cdn.com/v4/letter/t/76d3ee/32.png) [@tsp](https://discuss.kotlinlang.org/u/tsp)\
**Post date:** [April 25, 2024, 9:30pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/6 "2024-04-25T21:30:36Z")

</div>

but you’re likely not putting as much text inside each of the parentheses than the braces. As soon as it’s a multiline instruction, you’ll end up with a line

```auto
} {

```

and what does that represent? Will it be clear why that line is where it is, and why the two lambdas are separated like that? I doubt it.

---

<div class="post-metadata">

**Author:** ![hg42](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/hg42/32/10351_2.png) [@hg42](https://discuss.kotlinlang.org/u/hg42)\
**Post date:** [April 25, 2024, 9:45pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/7 "2024-04-25T21:45:45Z")

</div>

1. in a DSL it’s clear what it means

2. you think `} ) {` looks better?

as in

```auto
(xyz {
   line1
   line2
   ...
} ) {
   line1
   line2
   ...
}

```

I think this is more clear:

```auto
xyz {
   line1
   line2
   ...
} {
   line1
   line2
   ...
}

```

---

<div class="post-metadata">

**Author:** ![hg42](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/hg42/32/10351_2.png) [@hg42](https://discuss.kotlinlang.org/u/hg42)\
**Post date:** [April 25, 2024, 9:46pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/8 "2024-04-25T21:46:45Z")

</div>

> [@zergeone](#):
>
> It doesn’t matter if `x { } { }` is “good” or “bad” practice. It fits logically into the language design.

that’s one of my personal favorites. Usually, if the same thing ()() vs {}{} is handled differently there it will have it’s side effects

> [@tsp](#):
>
> None of you have provided an **actual** example where it’s obvious what the two lambdas each stand for.

and this doesn’t matter, either, simplicity, less rules to describe a difference that doesn’t really exist, consistency, orthogonality, enough reasons

language design is not about use cases or taste

e.g. look at python, list comprehensions and similar syntax is backwards for no reason, totally unreadable, just because someone thought it would be nice to imitate natural language

it’s more about reducing the number of rules to describe the language.

For example (again python) languages that need to distinguish statements from expressions get into trouble all the time (e.g. lambdas, that can only be expressions, why python?)

---

<div class="post-metadata">

**Author:** ![zergeone](https://avatars.discourse-cdn.com/v4/letter/z/96bed5/32.png) [@zergeone](https://discuss.kotlinlang.org/u/zergeone)\
**Post date:** [April 26, 2024, 7:57am UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/9 "2024-04-26T07:57:17Z")

</div>

Yes! It’s my main point.

`(` “somewhere behind” is ugly and must be avoided when possible.

`(one(arg1).two(arg2) ?: value).three(arg3)` is bad

and `one(arg).two(arg2).let { it ?: value }.three(arg3)` is much better.

It doesn’t matter if `x { } { }` is “good” or “bad” practice. It fits logically into the language design.

`(x { }) { }` is much worse.

`x {} () {}` solves “( somewhere behind” problem but it’s still ugly.

---

<div class="post-metadata">

**Author:** ![tsp](https://avatars.discourse-cdn.com/v4/letter/t/76d3ee/32.png) [@tsp](https://discuss.kotlinlang.org/u/tsp)\
**Post date:** [April 26, 2024, 8:55am UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/10 "2024-04-26T08:55:57Z")

</div>

Your response has done nothing to convince me that there is a legitimate use case for this syntax. None of you have provided an **actual** example where it’s obvious what the two lambdas each stand for.

---

<div class="post-metadata">

**Author:** ![zergeone](https://avatars.discourse-cdn.com/v4/letter/z/96bed5/32.png) [@zergeone](https://discuss.kotlinlang.org/u/zergeone)\
**Post date:** [April 26, 2024, 10:55am UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/11 "2024-04-26T10:55:34Z")

</div>

IMHO, no one will be able to provide example of legitimate use case of `() ()` and even of `operator invoke` itself in general.

There will always be an informative function name instead of ().

Meanwhile `() ()` is valid construction and `{} {}` is not. Does it make sense?

IMHO, this is the case when simplicity and uniformity of code interpretation by a compiler is more important than applicability of special cases

---

<div class="post-metadata">

**Author:** ![zergeone](https://avatars.discourse-cdn.com/v4/letter/z/96bed5/32.png) [@zergeone](https://discuss.kotlinlang.org/u/zergeone)\
**Post date:** [April 26, 2024, 12:56pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/12 "2024-04-26T12:56:06Z")

</div>

maybe this example is less ‘oversimplified’.Still not real code but maybe it’s more informative

```auto
interface RpcCaller<InterfaceType> {
    operator fun <MethodReturnType> invoke(call: (InterfaceType) -> MethodReturnType): MethodReturnType
}

interface Some {
    interface Options {
        var opt: Int
    }
    operator fun invoke(tuner: Options.() -> Unit): Int
}

interface Other {
    operator fun invoke(arg: Int): Int
}

interface SomeRpc {
    fun a(arg: Int): Int
    fun b(arg: Int): Some
    fun c(): Other
}

fun someFun(caller: RpcCaller<SomeRpc>) {
    val a = caller { it.a(1) } // ok
    val c = caller { it.c() } (arg = 0) // this works too!
    val b = (caller { it.b(2) }) { opt = 1 } // ugly workaround
    val b1 = caller { it.b(2) } () { opt = 1 } // less ugly workaround
    val b2 = caller { it.b(2) }.invoke { opt = 1 } // one more workaround
    val b3 = caller { it.b(2) } { opt = 1 } // error.
}

```

---

<div class="post-metadata">

**Author:** ![gidds](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/gidds/32/10865_2.png) [@gidds](https://discuss.kotlinlang.org/u/gidds)\
**Post date:** [April 26, 2024, 1:40pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/13 "2024-04-26T13:40:14Z")

</div>

You could replace:

```
.let{ it ?: value }

```

with the more readable:

```
.orElse(value)

```

if you defined something like:

```
public inline fun <T : Any> T?.orElse(value: T) = this ?: value

```

(Or if that were added to the stdlib as per [this ticket](https://youtrack.jetbrains.com/issue/KT-15962/orElse-extension-that-is-a-functional-version-of-the-Elvis-operator)…)

---

<div class="post-metadata">

**Author:** ![gidds](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/gidds/32/10865_2.png) [@gidds](https://discuss.kotlinlang.org/u/gidds)\
**Post date:** [April 26, 2024, 1:47pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/14 "2024-04-26T13:47:20Z")

</div>

> [@zergeone](#):
>
> no one will be able to provide example of legitimate use case of […] `operator invoke`

At the risk of getting sidetracked, there’s at least one common one: factory methods that look like constructors.

(Define an `operator invoke(…)` method in the companion object, and you then have something which is called exactly like a constructor, but can perform arbitrary operations before calling the primary constructor, can return a cached value instead of a new instance, can return a subclass, avoids many of the gotchas around order of initialisation, etc. — Of course, if a class has many of them, or their meaning isn’t obvious, then named methods would probably be better. But IME there are many cases where a simple `operator invoke` method is clean and simple.)

---

<div class="post-metadata">

**Author:** ![zergeone](https://avatars.discourse-cdn.com/v4/letter/z/96bed5/32.png) [@zergeone](https://discuss.kotlinlang.org/u/zergeone)\
**Post date:** [April 26, 2024, 2:06pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/15 "2024-04-26T14:06:18Z")

</div>

You’re right, but there’s a minor flaw

```auto
public inline fun <T : Any> T?.orElse(value: T) = this ?: value
fun c() {
    val a = 1.orElse(2) // no warnings
    val b = 1.let { it ?: 2 } // useful warning about non-nullable `?:` argument
}

```

---

<div class="post-metadata">

**Author:** ![hg42](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/hg42/32/10351_2.png) [@hg42](https://discuss.kotlinlang.org/u/hg42)\
**Post date:** [April 26, 2024, 7:22pm UTC](https://discuss.kotlinlang.org/t/chain-invokes-with-lambda-arguments/28478/16 "2024-04-26T19:22:42Z")

</div>

> [@gidds](#):
>
> ```auto
> .let{ it ?: value }
> 
> ```
> 
> with the more readable:
> 
> ```auto
> .orElse(value)
> 
> ```

while it’s true in this simple case, it’s also about statements vs expression.  
I prefer to “store” some intermediate values into descriptive names, before returning the the result expression,  
instead of a complicated expression, where you don’t see what each term means
