# Assignment not allow in while expression?

**URL:** <https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339>\
**Category:** Uncategorized\
**Created:** [January 5, 2013, 4:36am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339 "2013-01-05T04:36:08Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![saltnlight5](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/saltnlight5/32/1525_2.png) [@saltnlight5](https://discuss.kotlinlang.org/u/saltnlight5)\
**Post date:** [January 5, 2013, 4:36am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/1 "2013-01-05T04:36:08Z")

</div>

Hi,

In Java, I can do thing like this:

``

```kotlin
BufferedReader reader = new BufferedReader(reader);
String line = null;
while ((line = reader.readLine()) != null) {
  System.out.println(line);
}
```

However in Kotlin such thing is not allowed. I get error like **“Assignments are not expressions, and only expressions are allowed in this context”**

So the best I can come up with is something like this, but I wonder is there a better to write this in Kotlin? I like the Java syntax better because it’s shorter and easier for me to read.

``

```kotlin
var line : String?
do {
     line = reader.readLine()
     if (line == null)
          break
     println(line)
} while (true)
```

Thanks,  
Zemian

---

<div class="post-metadata">

**Author:** ![Tomsk](https://avatars.discourse-cdn.com/v4/letter/t/c6cbf5/32.png) [@Tomsk](https://discuss.kotlinlang.org/u/Tomsk)\
**Post date:** [January 7, 2013, 4:01pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/2 "2013-01-07T16:01:39Z")

</div>

So personally I'm quite glad that assignment is not an expression in Kotlin ... your version is shorter, but personally I don't find it easier to read. To my mind the second version more clearly expresses the (slightly unusual) control flow.

That said, hopefully eventually the Kotlin standard library will add an extension property to BufferedReader so that you can do something like this

``

```kotlin
for (line in reader.lines) {
  println(line)
}
```

If anyone is interested, here is the necessary property extension

``

```
import java.io.BufferedReader
import java.util.NoSuchElementException
val BufferedReader.lines: Iterator<String>
  get() = object : Iterator<String> {
  var line = this@lines.readLine()
  override fun next(): String {
          if (line == null)
           throw NoSuchElementException()
          val result = line!!           // no idea why !! is needed here, compiler bug?
          line = this@lines.readLine()
          return result
  }
  override fun hasNext() = line != null
  }
```

---

<div class="post-metadata">

**Author:** ![abreslav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/abreslav/32/8279_2.png) [@abreslav](https://discuss.kotlinlang.org/u/abreslav)\
**Post date:** [January 9, 2013, 11:06am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/3 "2013-01-09T11:06:59Z")

</div>

All you need is available in the standard library:

[http://jetbrains.github.com/kotlin/versions/snapshot/apidocs/kotlin/io/java/io/File-extensions.html#forEachLine](http://jetbrains.github.com/kotlin/versions/snapshot/apidocs/kotlin/io/java/io/File-extensions.html#forEachLine)(jet.String, jet.Function1)

---

<div class="post-metadata">

**Author:** ![saltnlight5](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/saltnlight5/32/1525_2.png) [@saltnlight5](https://discuss.kotlinlang.org/u/saltnlight5)\
**Post date:** [January 9, 2013, 4:40pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/4 "2013-01-09T16:40:51Z")

</div>

I think you guys miss the question I tried to ask. I undertand there is kotlin.io package that helps out the Java Stream/Reader classes. And I do see how higher function can help designing the API. However this is not my question in orginal post.

My question is more about the usage of the Kotlin while statment itself, I just happen to give you example using Reader class. Often cases I used the while loop in a case like the first post I gave, and I can capture result from a method all in the single line and then compare it inside the while expression. I understand there is may way to do the same, so I already provided one style, which Tom said he prefer it rather but I dislike. Out of all the Java verboseness, I find this particular case Java is good at. I am just stating this particular case and pointed Kotlin doesn’t support it and I miss it. You can take this as a feedback on your restriction of the while statement in kotlin I guess.

---

<div class="post-metadata">

**Author:** ![abreslav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/abreslav/32/8279_2.png) [@abreslav](https://discuss.kotlinlang.org/u/abreslav)\
**Post date:** [January 9, 2013, 6:37pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/5 "2013-01-09T18:37:20Z")

</div>

To be honest, the only use case for this idiom I (or my colleagues) ever came across is the one you mentioned in the post. Expressions with side effects are generally discouraged, so I think we do well enough in this case.

---

<div class="post-metadata">

**Author:** ![Tomsk](https://avatars.discourse-cdn.com/v4/letter/t/c6cbf5/32.png) [@Tomsk](https://discuss.kotlinlang.org/u/Tomsk)\
**Post date:** [January 9, 2013, 8:26pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/6 "2013-01-09T20:26:16Z")

</div>

So File.forEachLine works for files .... but it doesn't work for all the BufferedReader cases ... for example,

val reader = BufferedReader(StringReader(someStringData))

or

val reader = BufferedReader(InputStreamReader(myInputStream))

So the extension for BufferedReader is still pretty useful 🙂

---

<div class="post-metadata">

**Author:** ![programingjd](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/programingjd/32/1526_2.png) [@programingjd](https://discuss.kotlinlang.org/u/programingjd)\
**Post date:** [January 10, 2013, 10:13am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/7 "2013-01-10T10:13:18Z")

</div>

You could do it like this:

`   val reader = BufferedReader(reader)
  var line: String? = null;
  while ({ line = reader.readLine(); line }() != null) {
  System.out.println(line);
  }`

---

<div class="post-metadata">

**Author:** ![saltnlight5](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/saltnlight5/32/1525_2.png) [@saltnlight5](https://discuss.kotlinlang.org/u/saltnlight5)\
**Post date:** [January 10, 2013, 3:31pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/8 "2013-01-10T15:31:00Z")

</div>

Ah ha! Exellent workaround Jerome! Thank you very much for the tips.

I forgot that “{}” is a literal construct for jet.Function0 and we can enclose any var. This certainly avoided assignment inside direct while statment, but still able to store and capture the line var result. However this solution is bit heavy though, since we are creating a function object per each iteration. Interesting …

I am curious as why Kotlin wont’ simply allow assignment operator to be evaluated. That way, we can omit that “; line” part. 🙂

---

<div class="post-metadata">

**Author:** ![saltnlight5](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/saltnlight5/32/1525_2.png) [@saltnlight5](https://discuss.kotlinlang.org/u/saltnlight5)\
**Post date:** [January 10, 2013, 3:39pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/9 "2013-01-10T15:39:46Z")

</div>

Andrey,

```kotlin
To be honest, the only use case for this idiom I (or my colleagues) ever came across is the one you mentioned in the post.
```

That's not a good reason to not take feedback from users. :) If you search the "BufferedReader.readLine()" within JDK itself, you will see few occurance of the same usage. Also I see prentty out in the open source community.

---

<div class="post-metadata">

**Author:** ![abreslav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/abreslav/32/8279_2.png) [@abreslav](https://discuss.kotlinlang.org/u/abreslav)\
**Post date:** [January 10, 2013, 4:14pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/10 "2013-01-10T16:14:29Z")

</div>

My point was the the readLine() and read() use cases are the only ones out there. Since they are covered with the library, there's no need in this pattern at all.

---

<div class="post-metadata">

**Author:** ![Micah71381](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/micah71381/32/1527_2.png) [@Micah71381](https://discuss.kotlinlang.org/u/Micah71381)\
**Post date:** [February 1, 2015, 1:39am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/11 "2015-02-01T01:39:19Z")

</div>

A scenario where assignment is useful as an expression is one like:

```kotlin
class IntRange(public final val start: Int, public final val end: Int) : Iterable<Int> {
     override fun iterator(): Iterator<Int> = IntIterator(this)
}

class IntIterator(final val range: IntRange) : Iterator<Int> {
  private var current: Int = range.start
  override fun next(): Int = (current = current + 1) // this does not compile because an assignment isn’t an expression that returns the value assigned like in many other languages
  override fun hasNext(): Int = current <= range.end
}
```

This is a contrived case as an example, but the point is that having an assignment evaluate to the value of the assignment allows the programmer to assign a value and return it without having to assign and return as separate steps.

---

<div class="post-metadata">

**Author:** ![abreslav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/abreslav/32/8279_2.png) [@abreslav](https://discuss.kotlinlang.org/u/abreslav)\
**Post date:** [February 2, 2015, 12:01pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/12 "2015-02-02T12:01:31Z")

</div>

Why not use "++current"?

---

<div class="post-metadata">

**Author:** ![Micah71381](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/micah71381/32/1527_2.png) [@Micah71381](https://discuss.kotlinlang.org/u/Micah71381)\
**Post date:** [February 2, 2015, 9:08pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/13 "2015-02-02T21:08:33Z")

</div>

That only works if you are incrementing by 1.

```kotlin
++current
```

is the same as

```kotlin
{ current = current + 1; return current; }
```

In fact, ++i is a perfect example of an assignment as an expression and it is immensly useful.&nbsp;&nbsp;++i both assigns to i and as an expression it returns the value that was assigned to i.&nbsp;&nbsp;Increment and decrement operators are just examples of situations where assignments as expressions are very useful, I would just like to see them extended to more than the trivial increment-by-one and decrement-by-one operations.

For the slightly more complex case consider:

```kotlin
i += 2
```

To take it a little further:

```kotlin
current = FetchNext(current)
```

where FetchNext is some operation that gets the next item in a series from a remote source.

Currently, in Kotlin these would have to be,

```kotlin
{ i += 2; return i}
{ current = FetchNext(current); return current }
```

respectively.

---

<div class="post-metadata">

**Author:** ![abreslav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/abreslav/32/8279_2.png) [@abreslav](https://discuss.kotlinlang.org/u/abreslav)\
**Post date:** [February 3, 2015, 11:48am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/14 "2015-02-03T11:48:09Z")

</div>

Ok, I see your point.

Since these cases are not very common, the overhead is rather moderate and many code style guides explicitly prohibit using assignments as expressions, I think what we have now is a fair compromise.

---

<div class="post-metadata">

**Author:** ![Jacksgong](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/jacksgong/32/2210_2.png) [@Jacksgong](https://discuss.kotlinlang.org/u/Jacksgong)\
**Post date:** [November 27, 2016, 5:23am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/15 "2016-11-27T05:23:11Z")

</div>

How can I simplify the following similar code without performance reduce:

```
randomAccessFile.seek(offset)

var byteCount = randomAccessFile.read(buffer)
while (byteCount != -1){
    fos.write(buffer, 0, byteCount)
    byteCount = randomAccessFile.read(buffer)
}

```

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [November 27, 2016, 8:54am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/16 "2016-11-27T08:54:22Z")

</div>

The code you’ve posted is the correct way to implement this logic in Kotlin. Given that this pattern only comes up in a very small number of library functions, we don’t think that the language has to provide a way to simplify it.

---

<div class="post-metadata">

**Author:** ![Jacksgong](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/jacksgong/32/2210_2.png) [@Jacksgong](https://discuss.kotlinlang.org/u/Jacksgong)\
**Post date:** [November 27, 2016, 8:59am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/17 "2016-11-27T08:59:16Z")

</div>

Ok, got it, thanks for your awesome job!😁

---

<div class="post-metadata">

**Author:** ![vjache](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/vjache/32/2170_2.png) [@vjache](https://discuss.kotlinlang.org/u/vjache)\
**Post date:** [November 27, 2016, 7:44pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/18 "2016-11-27T19:44:19Z")

</div>

I don’t know is it much slower but there is also an option with ‘tailrec’:

```
tailrec fun copy(buffer:ByteArray, fos:OutputStream, randomAccessFile:RandomAccessFile) {
    val byteCount = randomAccessFile.read(buffer)
    if (byteCount != -1){
        fos.write(buffer, 0, byteCount)
        copy(buffer, fos, randomAccessFile)
    }
}

```

---

<div class="post-metadata">

**Author:** ![elizarov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/elizarov/32/2164_2.png) [@elizarov](https://discuss.kotlinlang.org/u/elizarov)\
**Post date:** [November 27, 2016, 8:42pm UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/19 "2016-11-27T20:42:52Z")

</div>

I personally prefer it this way

```auto
randomAccessFile.seek(offset)

while (true) {
    val byteCount = randomAccessFile.read(buffer)
    if (byteCount < 0) break
    fos.write(buffer, 0, byteCount)
}

```

IMHO, this is the most clear way to write this kind of code. No invisible side-effects, no code duplication, looping is explicit. No `var` at all, just a `val`.

As for lines, Kotlin’s null-safety features enable a much better idiom for all these kind of `readLine` iterations:

```auto
val reader = BufferedReader(reader)
while (true) {
    val line = reader.readLine() ?: break
    System.out.println(line);
}

```

I don’t miss Java-style pattern of using `readLine` at all. This is clearly much better. No `var`s and no `null`s here.

---

<div class="post-metadata">

**Author:** ![rodrigodev](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/rodrigodev/32/1682_2.png) [@rodrigodev](https://discuss.kotlinlang.org/u/rodrigodev)\
**Post date:** [December 14, 2016, 2:39am UTC](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339/20 "2016-12-14T02:39:01Z")

</div>

@Jacksgong Kotlin allows you to create your own _while_ (with blackjack and hookers?), so you can create an inlined function like this one:

```
inline fun <T> `while`(nextValue: () -> T, condition: (T) -> Boolean, body: (T) -> Unit) {
    var value = nextValue()
    while (condition(value)) {
        body(value)
        value = nextValue()
    }
}

```

And then you can use it like this everywhere you want:

```
`while`({ randomAccessFile.read(buffer) }, { it != -1 }) { byteCount ->
    fos.write(buffer, 0, byteCount)
}

```

[Next page](https://discuss.kotlinlang.org/t/assignment-not-allow-in-while-expression/339.md?page=2)
