What's the idea behind Arrow's Stream? How does it...
# arrow
s
What's the idea behind Arrow's Stream? How does it compare to Flow or RxJava?
s
Arrow's Stream is a straight up port of FS2 on top of Arrow Fx Coroutines instead of a typeclass hierarchy with
F
. Therefore it's a lot simpler in design since it uses
suspend
all over, instead of making the distincinction between
Pure
,
Infallible
etc Both
Flow
and
Stream
provide a pull based mechanism for streaming, but
Stream
splits itself in a
Pull
API and a
Stream
API.
Flow
offers APIs where you bridge different `Flow`'s to build combinators by using a
suspend
back-pressured system. (Typically you
collect
and re-emit on a different
Flow
). In contrast
Stream
offers a functional API where you can inspect/pull elements and the state of the
Stream
, but the focus on building custom operators is low since it aims to be a fully featured toolbox like RxJava where all operators live inside the library and user rely on composition. Therefore
Stream
has a mechanism for safely composing streaming resource, which is one of the strongest features of FS2. You can open a resource with
Stream.bracket
or
Stream.resource
and it automatically extends/closes the scope/resource depending on which compositonal operators are used. It also works
Chunk
based so it's a
Stream
that has
Array
of elements at its leaves instead of single elements, and it allows you to work in constant space on those `Chunk`s in its API.
RxJava
is a completely different beast on its own since its
push
based and also single element. Not sure if that fully answers your question so be sure to ask follow up questions if you have any!
❤️ 5
g
RxJava
 is a completely different beast on its own since its 
push
 based and also single element.
But why Flow is pull based?
s
KotlinX Flow is a pull based implementation.
Copy code
flow {
  emit(1)
  // Never reaches here until 1 is consumed
  emit(2)
}
A Pull based implementation is more desired over push based, since then the consumer has control over the producer at what speed it can produce elements so there is no concern of back-pressure. A slight trade-off is that with a push based model like RxJava the producer can eagerly produce values, but such things can also be modeled with a pull based system by offloading in a Queue (or Channel) with a strategy applied on the Queue.
more desired
Take that with a grain of salt, since some people might find push based more desired 😅 From the perspective of functional programming it's definitely more desired.
g
I see what you mean about “implementation”, so not consumption api, but way how you implement particular flow
it can be achieved with rxjava too, but it’s a lot more complicated to do properly
s
Thanks @simon.vergauwen Are you saying resource safety is harder to achieve with flow?
s
Yes, flow has no support for resource safety upon composition afaik. So it's up to the user to implement mechanism for resource safety, while in Arrow's Stream they're build in just like you would be using
IO.bracket
or
Resource
with
IO
.
s
Got it, thanks Simon
👍 1