RTS class/builder/typeclass instead of interpreting to IO #230
Comments
|
|
|
@jdegoes Can you elaborate on the benefits you refer to? We talked about this a bunch on Gitter and while I think it's a nice change, I don't see it being substantially different than what we have, though perhaps the details here lie in assumptions on how this would be implemented.
Regarding performance, returning I really see this proposal as a way to improve clarity -- I think it's confusing for people to look at a type class and see I generally support this proposal, though I'd like to see it further developed -- specifically, a PR that answers questions like:
|
|
Yeah, I don't see the giant performance improvement here. Can you explain it in more detail? |
|
There are are already a lot of people depending on cats-effect. I would prefer to get 1.0 out the door before considering foundational changes. |
|
Sorry, in my haste, I misspoke. Technically, it should be: an improvement to performance (because rewrapping and running in Without This not only removes the possibility of translating from At this point, there is no need for the cats effect data type to be bundled with the type classes, but instead, every reason to separate it out into its own module, or as I have suggested elsewhere, deprecate it in favor of Monix Task, since Alexandru currently maintains both of them. The overall approach of bundling dependencies (such as executors, scheduled executors, timers, etc.) into an
The laws for cats effect are not laws, more like bug finders, because equality is not definable on We could have bug finders for RTS implementations, at least for finding trivial bugs.
Are we talking 1.1 or 2.0? |
|
I still don't see the performance loss. In practice, I guess no one will convert to IO in their apps. For instance, Monix users working with Task, even when generically working with In the case they choose to use IOApp and convert their application Next, if we have I don't really see a practical difference except not using the cats IO type, I would be very surprised if there is a performance difference. |
|
@johnynek The worst case bound on Most libraries run effects everywhere due to interop with impure Java / Scala. I'm not saying performance is the reason to make this change (it's not), but it's a nice...um...side-effect. |
Let's call these bug finders "tests" ;) Terminology aside, the point is that middleware folks can rely on
How about the ability to do synchronous execution on Scala.js if there's no async boundary? (I realize such an instance wouldn't be available for many effect types unless auto-shifts are disabled -- another good reason to keep this capability in a separate trait.) I've found the ability to call
So we wouldn't have
Not clear to me yet, but I think we can be pretty aggressive with 2.0. 3-6 months from 1.0 feels right to me, giving us time to work through things like |
I don't agree with that. First of all, in our experience with Also you need def toIO[F[_], A](fa: F[A])(implicit F: ConcurrentEffect[F]): IO[A] =
IO.cancelable { cb =>
fa.runCancelable(r => IO(cb(r))).unsafeRunSync
}There's a nice symmetry here btw, between More problematic however, if we'd want to clean the API of I'm not even sure if it's possible and I'm saying this because I tried making it This is why for example I insist on keeping I'm open to implementing a
I totally agree and I'm in that same boat. We don't have time for any foundational changes for 1.0, what we have is good anyway, so any grand, breaking changes will get delayed for a version 2.0 at least. |
I may be wrong here, but I do not think this belongs in type Result[A] = Either[Throwable, A] // or whatever
def evaluate[A](fa: F[A]): F[Result[A]]
def evaluateStep[A](fa: F[A]): G[Either[Result[A], F[A]]]where The first one, You can then achieve
I think this is easy to provide. However, I'm very curious about the use cases. You do not have any compile-time guarantee about how much of the It seems like a synchronous effect type that can guarantee
Yes, exactly, you can get this functionality without baking it into
|
If you have the ability to cancel purely, and you have the ability to do run an effect impurely, then you already have the ability to cancel at the end of the world—by composition of the above orthogonal features. So you don't lose anything in expressiveness and you gain in a more minimal surface area.
In that case, they should be
If the type classes defining what it means to be an effect monad themselves require a concrete effect data type in order to fully specify semantics, then this is a gigantic failure of abstraction. Or a sign that abstraction over effects is impossible and the project's goals must necessarily fail. |
This satisfies same use case as https://github.com/typelevel/cats-effect/blob/master/core/shared/src/main/scala/cats/effect/Effect.scala#L74, right? E.g., if
Agreed, what I really want in such use cases is an effect type and associated type class that guarantees synchronous execution, along with an associated mechanism to run it at FFI boundaries. I can't safely write such code with the current type classes or with |
This seems sane, and it's worthwhile highlighting that a similar dichotomy emerged in the PureScript ecosystem between I'll incorporate these ideas into the Scalaz 8 type class hierarchy and perhaps that can inspire some revisions in cats-effect 2.0. |
|
Closing because this discussion has been mostly obsoleted by the more contemporary concepts of what we're going to do in CE 3. I'm also strongly opposed to abstracting over the evaluation of effects in this fashion, as it cannot be done safely or lawfully and will ultimately only constrain downstream implementors. Ultimately, it is also unnecessary, as the practical downsides to the current |
So discussing this in the scalaz room as well as the cats-effect room, @jdegoes brought up an interesting point: Why are the cats-effect typeclasses interpreting to
IOinstead of carrying each's runtime system?this is kind of where something like this may come in handy:
RTSis interesting to me because you don't even have to consider it a typeclass, it can just be a sort of immutable "builder" that can also carry the configuration you want in your runtime in the case that you happen to have a choice (like monix).It cuts out the middleman: In places like
http4swhere we have to interface with impure code at the server backends it reduces the need to have to hop throughIOfor the same thing in the first place.It's an interesting thing to consider. Then cats-effect typeclasses would have no need to have this middleman hop to express IO, you can just use them to express your
F[A]behavior and use the runtime to control theunsafeRunsemantics.The text was updated successfully, but these errors were encountered: