Creating Our Own Streams

Learn how to create different types of streams in Elixir

Streams are implemented solely in Elixir libraries. There’s no specific runtime support. However, this doesn’t mean we want to drop down to the very lowest level and create our own streamable types. The actual implementation is complex. Instead, we probably want to use some helpful wrapper functions to do the heavy lifting. There are a number of these, including cycle, repeatedly, iterate, unfold, and resource.

Let’s start with the three simplest: cycle, repeatedly, and iterate.

Stream.cycle

Stream.cycle takes an enumerable and returns an infinite stream containing that enumerable’s elements. When it gets to the end, it repeats from the beginning, indefinitely. Here’s an example that generates the rows in an HTML table with alternating green and white classes:

iex> Stream.cycle(~w{ green white }) |>
...> Stream.zip(1..5) |>
...> Enum.map(fn {class, value} ->
...> "<tr class='#{class}'><td>#{value}</td></tr>\n" end) |> 
...> IO.puts
<tr class="green"><td>1</td></tr> 
<tr class="white"><td>2</td></tr> 
<tr class="green"><td>3</td></tr> 
<tr class="white"><td>4</td></tr> 
<tr class="green"><td>5</td></tr> 
:ok

Stream.repeatedly

Stream.repeatedly takes a function and invokes it each time a new value is wanted.

iex> Stream.repeatedly(fn -> true end) |> Enum.take(3) 
[true, true, true]

iex> Stream.repeatedly(&:random.uniform/0) |> Enum.take(3) 
[0.7230402056221108, 0.94581636451987, 0.5014907142064751]

Stream.iterate

Stream.iterate(start_value, next_fun) generates an infinite stream. The first value is start_value. The next value is generated by applying next_fun to this value. This continues for as long as the stream is being used, with each value being the result of applying next_fun to the previous value. Here are some examples:

iex> Stream.iterate(0, &(&1+1)) |> Enum.take(5) 
[0, 1, 2, 3, 4]

iex> Stream.iterate(2, &(&1*&1)) |> Enum.take(5) 
[2, 4, 16, 256, 65536]

iex> Stream.iterate([], &[&1]) |> Enum.take(5) 
[[], [[]], [[[]]], [[[[]]]], [[[[[]]]]]]

Practice these commands in the given terminal:

Get hands-on with 1200+ tech skills courses.