forEach with elements as the receivers

I guess one other point I’d make about my suggestion. Even if the internal implementations don’t use the existing tools, we should probably still use existing concepts, since we already have all the necessary concepts for receiver functions and iteration. I think that would still get us to about the same names I suggested.

Considering that IntelliJ IDEA already adds a hint for multi-line receivers that implies this syntax, I believe this is the correct answer.

And since receivers are syntactic sugar to begin with, both an opt-in for non-receivers (i.e. this suggestion) and an opt-out for receivers (i.e. defining explicit variables to negate the receiver syntax and use regular lambda sequence) might be a good idea. Just seems weird to me to treat (T)->Unit and T.()->Unit as two entirely different things and having two of each method every time the user might prefer one syntax over the other.

1 Like

I did not expect this kind of success.

However this can be also a viable way to fix “Kotlin this overload”, where this become this + this@father + this@grandfather and so on.
This syntax can enforce this = it and requires explicit declaration of different this scope.

1 Like

I like this as well, but I like the following code as well:

list.withEach{ foo(key, value) }

(where list is List<Map.entree>)

Has this been considered?

val iterable = listOf(...)
withEach(iterable) {
    // .. receivers accessible here
}
public inline fun <T> Iterable<T>.withEachIndexedCount(action: T.(Int) -> Unit): Int {
    var index = 0
    for (item in this) item.action(checkIndexOverflow(index++))
    return index
}

I would remove the count from the name: withEachIndexed.
This is a closer match to forEachIndexed

Guys…it should be applyAll { }

Sounds consistent. Then again we don’t have a letAll, it is called map instead. So there is no consistency to begin with.

1 Like

I think giving the function a name that describes what it does is more important than consistency between the different function names. let, apply, run, with and also don’t map well t their collection based counterparts. I like applyAll. It describes what it does pretty well: “apply this lambda to all elements”.

That all said I don’t think naming this function is the real problem. I think it’s more of a usecase issue. I can’t remember any situation where I would have used this function and I don’t think I ever used for(a in foo) with(a){}.
The youtrack issue linked above only has 5 upvotes and I don’t see any real usecase described here or in that issue. I know this idea sounds like something that kotlin really needs but then how often would anyone really use this?


Also I suggest we restrict this discussion to use cases from now on. Otherwise this will just end up being the next mega thread that will be closed. We can argue about the best name when this function ever gets enough support to be implemented (but that’s just my oppinion).

The best thing about your syntax (if it becomes universal and not only part of forEach) is that I don’t have to decide in advance if “it” or “this” is better, the one who uses the function (in this case the forEach) can decide it. Deprecating apply would also be nice for newbies, if you need to look at this image everything (like I do) it’s a hint that it wasn’t good design to begin with: