This may sounds like I'm begging to start a flame war, but hear me out.
In some languages laziness is expensive. For example, in Ruby, where I have the most recent experience, laziness is slow because it's achieved using fibers, so it's only attractive when:
Otherwise you'll definitely want to use the normal, eager methods.
My initial investigation suggests that the overhead for laziness in Elixir is much lower (this thread on reddit backs me up), so there seems little reason to ever use Enum instead of Stream for those things which Stream can do.
Is there something I'm missing, since I assume Enum exists for a reason and implements some of the same functions as Stream. What cases, if any, would I want to use Enum instead of Stream when I could use Stream?
Streams are useful when working with huge, potentially infinite data sets. With large data sets, streams are more suitable as they do not fill up the memory with all the data at once, which Enum would do due to its intermediate lists.
The Enum module provides a huge range of functions to transform, sort, group, filter and retrieve items from enumerables. It is one of the modules developers use frequently in their Elixir code. The functions in the Enum module are limited to, as the name says, enumerating values in data structures.
Any enumerable that generates elements one by one during enumeration is called a stream. For example, Elixir's Range is a stream: iex> range = 1..
The methods in Stream essentially create a "recipe list" of transformations over your data while the methods in Enum actually resolve these transformations. So you eventually will have to use an Enum function to resolve your data transformation even if everything else is a Stream.
Also some concepts, namely Reduce, have no real meaning in Stream and you must use Enum.
As for performance, if you have a series of transformations you're performing, a possibly infinite stream of data, or you're reading a file, use Stream. If you've just one transformation over a finite enumerable or you need to resolve a Stream, use Enum.
For short lists, Stream will be slower than simply using Enum, but there's no clear rule there without benchmarking exactly what you are doing. There are also some functions that exist in Enum, but don't have corresponding functions in Stream. (for example, Enum.reverse )
The real reason you need both is that Stream is just a composition of functions. Every pipeline that needs results, rather than side effects needs to end in an Enum to get the pipeline to run.
They go hand in hand, Stream couldn't stand alone. What Stream is largely doing is giving you a very handy abstraction for creating very complex reduce functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With