What's the idiomatic way to have a 'side effect' in a functional pipe?

Take for example this (infinite) sequence and its subsequent use:

fun  fibonacciNumbers(f0: Int=0, f1: Int=1): Sequence<Int> = sequence {
    yield(f0)
    yieldAll(fibonacciNumbers(f1, f0+f1))
}

fibonacciNumbers()
  .map { it.apply { println(it) } }
  .takeWhile { it < 1_000_000 }
  .count()

Notice the completely artificial use of map in order to achieve a side effect while keeping the sequence intact.

What is the idiomatic way to do that ?

also()

Okay, perhaps that deserved slightly more than a one-word answer! But that’s basically it.

Your line:

.map { it.apply { println(it) } }

could be written as:

.also{ println(it) }

That’s exactly what the function was intended for, and it’s a fairly common pattern.

Have you tried this?
For me it does not produce the same result - the numbers are not printed; the Sequence object is printed instead, which is actually expected, given the definition of also()

onEach does the job:

fibonacciNumbers()
  .onEach { println(it) } 
  .takeWhile { it < 1_000_000 }
  .count()
4 Likes