Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream.into + Stream.run identical to Enum.into?

Tags:

elixir

Elixir allows you to use Streams instead of Enums to prevent intermediary copies of collections. But when you're on the last step, would it even matter?

Even when you get to the smallest details isn't this

Stream.concat(header, rows)
|> CSV.encode
|> Stream.into(output)
|> Stream.run

the same as this?

Stream.concat(header, rows)
|> CSV.encode
|> Enum.into(output)

If so, why would the Stream.into/3 docs advocate the pairing of Stream.into + Stream.run and not just say Enum.into?

Perhaps it's a simple as just being more readable and discoverable.

like image 848
dimroc Avatar asked Oct 14 '25 04:10

dimroc


1 Answers

Your two examples don't really do the same thing. The first one just runs the stream pipeline, while the second one will also give you a return value. Since you are not using the result, Stream.run is just fine in this case.

Generally, if you're interested in the result of a stream you can always use the Enum counterparts in the last step of a pipeline. Stream.run will not return the results, but rather apply the pipeline and then return :ok. This is useful if you're interested in the side effects rather than the actual return value.

I suppose the reason we have Stream.into as well is that it might not actually be the last step in the pipeline. Here's a contrived example:

output = IO.stream(:stdio, :line)

Stream.iterate(0, &(&1 + 1))
|> Stream.chunk(2, 1)
|> Stream.into(output, &"BEFORE: #{inspect &1}\n")
|> Stream.map(fn [x, y] -> x * y end)
|> Stream.into(output, &"AFTER: #{inspect &1}\n")
|> Stream.take(3)
|> Stream.run

Which will output

BEFORE: [0, 1]
AFTER: 0
BEFORE: [1, 2]
AFTER: 2
BEFORE: [2, 3]
AFTER: 6
like image 181
Patrick Oscity Avatar answered Oct 17 '25 20:10

Patrick Oscity



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!