<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><div style="background-color: #ffffff; color: #080808;" data-mce-style="background-color: #ffffff; color: #080808;"><div>Hi David,</div><div>You can always transform an imperative code to a stream by pushing the element through a consumer.</div><div>Internally, a stream uses a push iterator (see Spliterator.tryAdvance(consumer)).</div><div><br data-mce-bogus="1"></div><div>As a silly example, this is a way to write fibonacci (the recursive form) with a stream right in the middle.</div><pre style="font-family: 'JetBrains Mono',monospace; font-size: 11.3pt;" data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 11.3pt;"><span style="color: #0033b3;" data-mce-style="color: #0033b3;"><br>static void </span><span style="color: #00627a;" data-mce-style="color: #00627a;">fibo</span>(<span style="color: #0033b3;" data-mce-style="color: #0033b3;">int </span><span style="color: #000000;" data-mce-style="color: #000000;">n</span>, <span style="color: #000000;" data-mce-style="color: #000000;">IntConsumer consumer</span>) {<br>  <span style="color: #0033b3;" data-mce-style="color: #0033b3;">if </span>(<span style="color: #000000;" data-mce-style="color: #000000;">n </span>< <span style="color: #1750eb;" data-mce-style="color: #1750eb;">2</span>) {<br>    <span style="color: #000000;" data-mce-style="color: #000000;">consumer</span>.accept(<span style="color: #000000;" data-mce-style="color: #000000;">n</span>);<br>    <span style="color: #0033b3;" data-mce-style="color: #0033b3;">return</span>;<br>  }<br>  <span style="color: #0033b3;" data-mce-style="color: #0033b3;">var </span><span style="color: #000000;" data-mce-style="color: #000000;">result </span>= <span style="color: #000000;" data-mce-style="color: #000000;">Stream</span>.<span style="font-style: italic;" data-mce-style="font-style: italic;">of</span>(<span style="color: #067d17;" data-mce-style="color: #067d17;">""</span>)<br>      .mapMultiToInt((<span style="color: #000000;" data-mce-style="color: #000000;">_</span>, <span style="color: #000000;" data-mce-style="color: #000000;">consumer2</span>) -> {<br>        <span style="font-style: italic;" data-mce-style="font-style: italic;">fibo</span>(<span style="color: #851691;" data-mce-style="color: #851691;">n </span>- <span style="color: #1750eb;" data-mce-style="color: #1750eb;">1</span>, <span style="color: #000000;" data-mce-style="color: #000000;">consumer2</span>);<br>        <span style="font-style: italic;" data-mce-style="font-style: italic;">fibo</span>(<span style="color: #851691;" data-mce-style="color: #851691;">n </span>- <span style="color: #1750eb;" data-mce-style="color: #1750eb;">2</span>, <span style="color: #000000;" data-mce-style="color: #000000;">consumer2</span>);<br>      })<br>      .sum();<br>  <span style="color: #000000;" data-mce-style="color: #000000;">consumer</span>.accept(<span style="color: #000000;" data-mce-style="color: #000000;">result</span>);<br>}<br><br><span style="color: #0033b3;" data-mce-style="color: #0033b3;">static void </span><span style="color: #00627a;" data-mce-style="color: #00627a;">main</span>() {<br>  <span style="font-style: italic;" data-mce-style="font-style: italic;">fibo</span>(<span style="color: #1750eb;" data-mce-style="color: #1750eb;">7</span>, <span style="color: #000000;" data-mce-style="color: #000000;">IO</span>::<span style="font-style: italic;" data-mce-style="font-style: italic;">println</span>);<br>}</pre></div><br></div><div>Here, I use mapMulti() to convert the imperative code to a Stream</div><div>(there is no factory method on Stream that takes a consumer of consumer).</div><div><br data-mce-bogus="1"></div><div>If you also want to short-circuit, you can use a gatherer instead of mapMulti but short-circuiting the recursive code will require to use an exception as control flow (it will not be pretty).</div><div><br data-mce-bogus="1"></div><div>regards,</div><div>RĂ©mi</div><div><br data-mce-bogus="1"></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"David Alayachew" <davidalayachew@gmail.com><br><b>To: </b>"core-libs-dev" <core-libs-dev@openjdk.org><br><b>Sent: </b>Tuesday, November 11, 2025 4:36:29 AM<br><b>Subject: </b>Difficulties of recursion with Streams<br></blockquote></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div dir="ltr"><div class="gmail_default" style="font-family:monospace">Hello <a class="gmail_plusreply" id="plusReplyChip-1" href="mailto:core-libs-dev@openjdk.org" tabindex="-1" target="_blank">@core-libs-dev</a>,</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">When working with streams, I often run into situations where I have to "demote" back to imperative code because I am trying to solve a problem best solved by recursion.</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">Consider the common use case of cycling through permutations to find all permutations that satisfy some condition. With recursion, the answer is incredibly simple -- just grab an element from the set, then call the recursive method with a copy of the set minus the grabbed element. Once you reach the empty set, you've reached your terminal condition.</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">Use cases like that are not only incredibly common, but usually,  embarrassingly parallel. The example above of cycling through permutations is only a few lines of imperative code, but I struggle to imagine how I would do this with Streams.</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">I guess let me start by asking -- are there any good ways currently to accomplish the above permutation example with Streams? And if not, should there be?</div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">Thank you for your time and consideration.</div><div class="gmail_default" style="font-family:monospace">David Alayachew</div></div><br></blockquote></div></div></body></html>