-
From what I saw in Samples in the source code as well as in announcement here StreamT<M, A> is a monad wrapper around
Don't get me wrong, I'm pretty sure, this type was very challenging to create. But most of its samples are easier to do with LINQ for objects and LINQ performance is Way better. So, does it worth our attention and maintenance effort? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
I'm not Paul, but I believe the purpose of StreamT is precisely that it "behaves like IO"; you can stream and transform values akin to an Observable, but can also run side effects in a principled, functional way. The value proposition is thus, like the entirety of the rest of the library, more related to composability and maintainability of client code, and other qualitative things, rather than specific quantitative measures necessarily (although there's always room for improvement). Since the purpose and usefulness of StreamT thus bound up with the usefulness of the IO monad in general, It's not surprising that very basic collection processing tasks, such as retrieving the last value, are more performant using types more specialized to said collection processing. |
Beta Was this translation helpful? Give feedback.
-
I've marked @micmarsh's answer as the correct one. But, just to expand:
This is not true.
This is not true.
This is not true.
Only partially true. Seeing as LINQ for Objects can't actually do what this does. @micmarsh got it absolutely right. Although this isn't only to do with This is a monad transformer that can lift anything. It doesn't have to be IEnumerable<IO<int>> mmx = // create an enumerable of IO;
var mmr = mmx.Select(mx => IO.pure(mx.Run(XXX) * 10))
.Select(mx => IO.pure(mx.Run(XXX) + 1)); Where the The above code looks like this for StreamT<IO, int>> mx = // create a stream of IO;
var mr = mx.Map(x => x * 10)
.Map(x => x + 1);
You don't understand what it does. And so, coming here to tell me I'm doing it wrong, like I have no idea what I'm doing, is really not going to sit well with me. You didn't even write your benchmarks accurately. None of the non- The critical thing that you miss is what @micmarsh points out:
This is exactly the correct point. We give up some processing to have code that we can maintain for the long-term. We give up some processing to have code that we can compose with other previously written code, making it easier for us to read and write code. It is also expected that the thing that gets lifted is a side-effecting operation, like And finally, this is a brand new feature. It is in beta. I am still working on it. And I will improve the performance over time. But the most important thing right now is that it is correct. There are performance limitations to the approach, but there's probably some additional gains to be made. Developers who know me well know that when it comes to hardcore performance tuning, I'm one of the best (a side-effect of my history). If there are gains to be made, I'll find them. Right now though, it just isn't a priority. My suggestion to you is that before you start picking apart bits of this library, you try to fundamentally understand what it's about. You wouldn't be suggesting these things if you fully understood what It will always be possible to write handwritten boilerplate-ridden solutions that are faster than the general-purpose types and functions in this library. You could improve the performance of your |
Beta Was this translation helpful? Give feedback.
I'm not Paul, but I believe the purpose of StreamT is precisely that it "behaves like IO"; you can stream and transform values akin to an Observable, but can also run side effects in a principled, functional way. The value proposition is thus, like the entirety of the rest of the library, more related to composability and maintainability of client code, and other qualitative things, rather than specific quantitative measures necessarily (although there's always room for improvement).
Since the purpose and usefulness of StreamT thus bound up with the usefulness of the IO monad in general, It's not surprising that very basic collection processing tasks, such as retrieving the last value, ar…