# Is \`with\` really good, idiomatic Kotlin?

**URL:** <https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292>\
**Category:** Uncategorized\
**Created:** [March 22, 2021, 11:41am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292 "2021-03-22T11:41:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [March 22, 2021, 11:41am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/1 "2021-03-22T11:41:05Z")

</div>

On the [idioms](https://kotlinlang.org/docs/idioms.html#call-multiple-methods-on-an-object-instance-with) page of the official documentation is this example for the usage of `with`:

```kotlin
val myTurtle = Turtle()
with(myTurtle) { //draw a 100 pix square
    penDown()
    for (i in 1..4) {
        forward(100.0)
        turn(90.0)
    }
    penUp()
}

```

However, I don’t think that it is good code! In larger code blocks it leads to a more or less unreadable mess, because it is unclear what calls refer to the implicit receiver given in the `with` block. I don’t see a good reason why one wants to use this (terrible!) coding style. To save a few key strokes?

The only valid scenario, I can imagine, is, when _all_ nested calls refer to the object given by `with`:

```auto
val myTurtle = Turtle()
with(myTurtle) {
    penDown()
    forward(100.0)
    turn(90.0)
    penUp()
}

```

But how often do we see such a simple code? I’d say, not so often. And just to support rare simple cases, it is not worth to offer a tool that deludes developers to write bad code.

There is a reason why `with` has been [fallen out of favor in the JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with) community:

> Using `with` is not recommended, and is forbidden in ECMAScript 5 [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). The recommended alternative is to assign the object whose properties you want to access to a temporary variable.

I would even go as far as deprecating `with` in Kotlin! But at least I wouldn’t recommend it as “idiomatic”. It is just bad style.

What is your opinion?

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [March 22, 2021, 7:11pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/2 "2021-03-22T19:11:57Z")

</div>

I @medium,  
I partly agree with you.

I suppose you made some mistakes in your post, primary you start from two different language (Kotlin and Javascript) to deduce the same assertion.

The `with` issue affects also `apply` and `run`.

```kotlin
turtle.apply { ... }
turtle.run { .. }

```

Unfortunately it is pretty easy to put instances in the scope, this is a Kotlin’s feature partly improved in DSL.  
This is an interesting feature but it is pretty easy to abuse.

---

<div class="post-metadata">

**Author:** ![brunojcm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/brunojcm/32/5116_2.png) [@brunojcm](https://discuss.kotlinlang.org/u/brunojcm)\
**Post date:** [March 23, 2021, 11:04am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/3 "2021-03-23T11:04:59Z")

</div>

What is so bad about `with`? What are the alternatives for the code you say is bad?

---

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [March 23, 2021, 11:05am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/4 "2021-03-23T11:05:02Z")

</div>

How easy it is to abuse these features is exactly my point. I’ve seen terrible code overusing these “scope functions” in Kotlin. It is a bit like Scala has lots of clever features, that are really easy to abuse in hard to imagine ways. Long story short: I think functions like `with` do more harm than good.

> [@fvasco](#):
>
> improved in DSL

What do you mean with this statement?

---

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [March 23, 2021, 11:08am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/5 "2021-03-23T11:08:11Z")

</div>

Bad is that calls in a `with` block are not limited to the _one_ receiver object. Actually this block can contain arbitrary code and it is really hard to read what call refers to the receiver object and what is a usual function call. Scala received a lot of criticism for “implicit parameters” for similar reasons. One of the most important quality aspects of code is that it is easy to reason about.

---

<div class="post-metadata">

**Author:** ![chipays](https://avatars.discourse-cdn.com/v4/letter/c/ad7895/32.png) [@chipays](https://discuss.kotlinlang.org/u/chipays)\
**Post date:** [March 23, 2021, 11:52am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/6 "2021-03-23T11:52:59Z")

</div>

> it is unclear what calls refer to the implicit receiver given in the `with` block

How is `with` any different from other receiver functions in this regard?

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [March 23, 2021, 1:04pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/7 "2021-03-23T13:04:37Z")

</div>

> **[Type-safe builders | Kotlin](https://kotlinlang.org/docs/type-safe-builders.html#scope-control-dslmarker)**

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [March 23, 2021, 2:41pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/8 "2021-03-23T14:41:13Z")

</div>

> [@medium](#):
>
> There is a reason why `with` has been [fallen out of favor in the JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with) community:
> 
> > Using `with` is not recommended, and is forbidden in ECMAScript 5 [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). The recommended alternative is to assign the object whose properties you want to access to a temporary variable.

Yes, there are reasons why with is broken in JavaScript, but those reasons cannot be applied to Kotlin’s with because it works fundamentally different to JavaScript’s with.

In JavaScript with enables ways to introduce bugs that cannot happen with Kotlin’s with.

---

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [March 23, 2021, 7:27pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/9 "2021-03-23T19:27:31Z")

</div>

`with` is not special in this regard. The same problem can happen with `let` and other scope functions. While useful, there should be some kind of warning in the documentation. Maybe I’ll make a pull request to add it to the documentation, but I wanted to make sure, that I’m not alone with my point of view.

Maybe my analogy with JavaScript’s `with` was not a good match, so better forget it. My point has actually nothing to do with JavaScript.

---

<div class="post-metadata">

**Author:** ![larcos.1](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/larcos.1/32/8115_2.png) [@larcos.1](https://discuss.kotlinlang.org/u/larcos.1)\
**Post date:** [March 24, 2021, 1:01pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/10 "2021-03-24T13:01:55Z")

</div>

I don’t think we should blame the tool if developers abuse it. I like using **with** to shorten assignment statements.  
`val noteKey = with(advisingNote) { NoteKey(emplid, institutionId, noteId) }`

The alternative would be:  
`val noteKey = NoteKey(advisingNote.emplid, advisingNote.institutionId, advisingNote.noteId)`

I feel like it reduces noise.

---

<div class="post-metadata">

**Author:** ![mice777](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mice777/32/4560_2.png) [@mice777](https://discuss.kotlinlang.org/u/mice777)\
**Post date:** [March 24, 2021, 2:16pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/11 "2021-03-24T14:16:27Z")

</div>

I agree, I use often let, run, also, apply, but I never use with because I don’t find good usage for this. Also it can be replaced by run.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [March 24, 2021, 3:15pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/12 "2021-03-24T15:15:27Z")

</div>

I prefer with over run, when I can start a function expression body with it:

```
fun Bar.foo(baz: Baz) = with(baz) {

}

```

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [March 24, 2021, 5:17pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/13 "2021-03-24T17:17:24Z")

</div>

Another interesting usecase for `with` is context-oriented programming - I think @darksnake wrote an article about it: [An introduction to context-oriented programming in Kotlin | by Alexander Nozik | ProAndroidDev](https://proandroiddev.com/an-introduction-context-oriented-programming-in-kotlin-2e79d316b0a2?gi=fad091f3990d)  
I think [kmath](https://github.com/mipt-npm/kmath) is designed that way.

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [March 24, 2021, 5:41pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/14 "2021-03-24T17:41:42Z")

</div>

Indeed, there is a [second one](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814?gi=b14cdfae8443) with more advanced examples. In Kmath we use scope-contexts (using `with` or `run`) to define lexical scopes with specific mathematic rules. And multiple receivers will make the framework even more advanced.

---

<div class="post-metadata">

**Author:** ![cylab](https://avatars.discourse-cdn.com/v4/letter/c/b5ac83/32.png) [@cylab](https://discuss.kotlinlang.org/u/cylab)\
**Post date:** [March 26, 2021, 10:54am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/15 "2021-03-26T10:54:43Z")

</div>

I hope this is just a bad example, because declaring an extension-function and then changing the receiver to the argument instead of the extended type seems like exactly the code that the OP is criticizing…

Other than that, I think receiver functions help to reduce noise and make the code more readable.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [March 26, 2021, 11:51am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/16 "2021-03-26T11:51:20Z")

</div>

It was a deliberately chosen example.

First of, I don’t think there is a big difference regarding this argument, as to what can be done with “with” and what can be done with “importing package-level members”. I like to see the “with” as some kind of import.

Second, my example is not bad for the same reasons why it is bad in JavaScript. When using “with” in JavaScript you cannot be sure at compile time which property you are currently accessing. In contrast, the property is determined at compile time in Kotlin, even in my example.

Having said that, I agree that using it can lead to bad code. I just don’t agree that using inherently leads to bad code.

---

<div class="post-metadata">

**Author:** ![westnordost](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/westnordost/32/6008_2.png) [@westnordost](https://discuss.kotlinlang.org/u/westnordost)\
**Post date:** [March 26, 2021, 2:07pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/17 "2021-03-26T14:07:02Z")

</div>

I agree with @medium . Basically I find that all constructs with lambdas that change what `this` is was a bad language decision for Kotlin and I avoid it where I can. I mentioned it before, I called it `this`-confusion.

One needs the IDE to assist one with pointing out what `this` is, and the fact that one needs the IDE to assist here already speaks for itself.

What I find acceptable, even if it is within another class, would be something like this:

```auto
fun Turtle.drawCornerRight() {
    penDown()
    forward(100.0)
    turn(90.0)
    penUp()
}

```

because one can directly read on the function signature what is `this`. When using `with` etc, one needs to know that already.

---

<div class="post-metadata">

**Author:** ![cantanima](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/cantanima/32/7439_2.png) [@cantanima](https://discuss.kotlinlang.org/u/cantanima)\
**Post date:** [April 1, 2021, 11:06pm UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/18 "2021-04-01T23:06:03Z")

</div>

Sorry I’m late to this party. If it interests anyone:

- Modula-2 had a similar `with` statement long ago. For reasons I don’t understand, Wirth must not have liked it, since he dropped those semantics when he simplified Modula-2 to Oberon, while redefining `with` to mean something else.

- Ada has a nice alternative IMHO. You can do this:

---

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [April 5, 2021, 5:05am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/19 "2021-04-05T05:05:36Z")

</div>

But Ada’s `renames` statement is _not_ like Kotlin’s `with`, because the receiver is not implicit. I think an explicit receiver would make things more clear in Kotlin, too.

---

<div class="post-metadata">

**Author:** ![cantanima](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/cantanima/32/7439_2.png) [@cantanima](https://discuss.kotlinlang.org/u/cantanima)\
**Post date:** [April 5, 2021, 5:23am UTC](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292/20 "2021-04-05T05:23:20Z")

</div>

> But Ada’s `renames` statement is _not_ like Kotlin’s `with` , because the receiver is not implicit.

Correct; that’s why I wrote, “Ada has a nice **alternative** IMHO.” You criticized (as I understood) the fact that the receiver in a `with` expression is implicit. The receiver in the Ada approach is explicit but you don’t have to write `longVariableName` over and over. As far as I can tell, that’s the only reason to use `with`.

If I misunderstood your intent, then never mind.

[Next page](https://discuss.kotlinlang.org/t/is-with-really-good-idiomatic-kotlin/21292.md?page=2)
