For - else clause


#1

Requesting else block with loop statement which won’t iterate.

for (i in emptyList<Int>()) {
    // This won't execute
} else {
    // this will executed
}

#2

forEach modified

fun main(vararg args: String) {
    emptyList<Int>().forElse {
        println("This won't execute")
    } ?: println("this will executed")
}

fun <T> Collection<T>.forElse(block: (T) -> Unit) = if (isEmpty()) null else forEach(block)

#3

I too have wished for a language to adopt such a feature. I seem to remember some language having such a feature, but I don’t remember which.

There may be some confusion however with other languages. Python has a for-else (http://book.pythontips.com/en/latest/for_-_else.html#else-clause) but in that case the else is executed when the loop finishes normally (i.e. no break).


#4

Following the pattern of first() and firstOrNull() methods, might be better to call it forEachOrNull


#5

Also can do

inline fun <T> Collection<T>.forEachOrNull(block: (T) -> Unit) = takeUnless(isEmpty()).forEach(block)

#6

Or you can do something like this:

infix inline fun <T> List<T>.orElse(predicate: () -> Unit){
    if (this.count() == 0) predicate()
}

infix inline fun <T> List<T>.forElse(predicate: (T) -> Unit) : List<T> {
    this.forEach(predicate)
   	return this
}

fun main(args: Array<String>) {
    (0 until 0)
    .toList() forElse {
        println(it)
    } orElse {
        println("It's empty")
    }
}

#7

Using only standard language & stdlib functions it looks Ok and quite readable IMHO:

myList.apply { 
    forEach { 
         println("This executes on each item $it")
    }
    if (isEmpty()) { 
        println("This executes when list is empty")
    } 
}

#8

The issue about this feature is https://youtrack.jetbrains.com/issue/KT-476.
You can vote for it, if you find it useful. Also, if you could post a concrete example, how would you use that feature, it would make your vote more substantial.


#9

Well how beautiful is Kotlin ?! It allows us to do what we want with what it has, and it has exactly what we want


#10

In this case, we’re lucky that Kotlin can do it with what it has. In many other cases, you can’t. A macro facility would be very nice to have.

(I’m not talking about C-style macros here, but rather something like Lisp or Elixir).