v0.10 represents a big milestone for the upcoming 1.0.0
(see milestones), bringing you the new and improved IO
data type, along with new type classes in support of cancelation.
But first, we now have a documentation website:
typelevel.org/cats-effect/
Checkout the document for IO
:
typelevel.org/cats-effect/datatypes/io.html
And also the published ScalaDocs:
typelevel.org/cats-effect/api/
Note: this release is binary compatible with 0.9, but not source compatible, as it has some small API cleanups, deprecated via private[package]
— see below for details 😉
Features for cancelation:
- #121: the cancelable
IO
- #132 and #133: added the
Timer
data type, to be able to do delayed execution and time measurements in a pure way, while also curing IO's heavy dependency onExecutionContext
- #134: adds the new
Concurrent
andConcurrentEffect
type classes, to complement the existing type classes with cancelation capabilities - #137, #142 and #145: adds
race
andracePair
inIO
and in theConcurrent
type class, for describing race conditions - #135, #143, #147, #149, #151, #153, #155, #156, #157: starts a documentation Microsite for Cats-effect, w00t!
Improvements for the provided instances:
- #144: re-adds
cats.data.Kleisli
instances, useful for example for Frameless, coupled with #2185 incats-core
in order to preserve coherence - #146: optimizes our internal
AndThen
implementation, currently used for makingIndexedStateT
stack safe for left-associated binds — this will soon be gone from cats-effect though, due to PR #2187 being merged incats-core
Other:
- #130: changed copyright headers in source files to mention a year range, plus it makes it clear that copyright is held by contributors
API breakage
This version is binary compatible with version 0.9, so you can upgrade cats-effect
without worries for your other dependencies. However it contains some minor API cleanups that might make your compiler to emit errors.
Async#shift
is now deprecated:
trait Async[F[_]] extends Sync[F] with LiftIO[F] {
// ...
@deprecated("Moved to Async$.shift, will be removed in 1.0", "0.10")
private[effect] def shift(ec: ExecutionContext): F[Unit] =
Async.shift(ec)(this)
Async#shift
was moved to the Async
companion object. So code like this:
def execute[F[_]](thunk: => A)(implicit F: Async[F], ec: ExecutionContext): F[A] =
F.shift *> F.delay(thunk)
Needs to be changed to ...
def execute[F[_]](thunk: => A)(implicit F: Async[F], ec: ExecutionContext): F[A] =
Async.shift[F](ec) *> F.delay(thunk)
The reason for the hard deprecation is that there's no potential for optimization and so it doesn't belong on the Async
type class, the derived implementation being the best you can do, in terms of the provided ExecutionContext
. It also forces apps to prepare for the upcoming 1.0.0
sooner.
IO.fromFuture
no longer requires an ExecutionContext
In case you used IO.fromFuture
, it was using an ExecutionContext
, but now with 0.10
it will stop doing that ...
import scala.concurrent.ExecutionContext.Implicits.global
IO.fromFuture(IO(Future(1 + 1)))
What happens with the upgrade to 0.10 is that the provided context in this sample will stop being used. So the compiler or the IDE might end up emitting an "unused import" warning.
But if you provided the ExecutionContext
explicitly, then this is going to be a compilation error:
// This triggers an error in 0.10
IO.fromFuture(IO(Future(1 + 1)))(global)
Note that the old symbols in both cases are still there, but made private[package]
— so binary compatibility is preserved.