Kotlin Iterator - range-based for loop in JavaScript


#1

Hello. I am implementing some JS modules for node.js in Kotlin, I am really enjoying the experience so far, so thanks for the brilliant work on a brilliant language.

However one type of the library that’s supposed to be used from JavaScript is a MutableIterable. What I’ve noticed is that Kotlin code like this:
for (i in smi) println(i.toString())

gets transpiled to JavaScript like this:

while (tmp$.hasNext()) {
  var j = tmp$.next();
  println(j.toString());
}

instead of a JS range-based for loop like for (val i of smi)

While the Kotlin MutableIterator/MutableIterable work just fine on the JVM I cannot actually use a range-based for loop on the Kotlin module in node. Is this a thing or am I just missing something? Thanks!


#2

Kotlin does not support emitting ES6+, so it won’t generate for..of. Currently, for..in in Kotlin works via Kotlin iterators producing the JS code you mentioned, it should work. Do you have any problems with it?


#3

@Alexey.Andreev, ah, of course, that makes sense. Thank you.

Well, since it’s a priority queue I decided it better to add a popAll method instead, but will try it out when I can get around to it and let you know if there is problem. Thank you for the reply :slight_smile:


#4

@Alexey.Andreev : Thanks for the reply. Just to make one thing clear: If we define a custom iterator for a class in Kotlin, and then we transpile it to Javascript (using CommonJS in the settings), is there any way in which then we can actually iterate that object with a for…in or for…of loop?
for…of loop gives an error in javascript, and for…in doesn’t crash but it doesn’t actually iterate the object.
As a very small example:

class MyIterable() : Iterable<Int> {
    var data : ArrayList<Int> = arrayListOf()
    fun push(x : Int) {
        data.add(x)
    }
    override fun iterator() : Iterator<Int> = data.iterator()
}

If i then declare an object of this class and push a couple of items, doing

for (i in myObj) println(i)

This will work fine in Kotlin, of course. But the transpiled code will not actually iterate in Javascript. If i do

for (var i in myObj) console.log(myObj[i]);

It gives an output like this:

ArrayList { modCount: 3, 'array_9xgyxj$_0': [ 2, 3, 4 ] }
[Function]
[Function]
[Function]

Also tried using Kotlin iterators created with the AbstractIterator and MutableIterator classes. From your answer, I guess that it’s not possible for now to create an iterator that will work as such in Javascript, but just wanted to make sure. Thanks! :slight_smile: