A compatible layer for scala.concurrent
with extra type parameters to
control ExecutionContext
s.
A compatible layer for scala.concurrent
with extra type parameters to
control ExecutionContext
s. Deliberately uses the same names as the
equivalent concepts in scala.concurrent
.
The trouble with sc.ExecutionContext is that it is used incoherently.
This leads to the problems described in
https://failex.blogspot.com/2020/05/global-typeclass-coherence-principles-3.html
. The extension layer in this package adds a phantom type parameter to
ExecutionContext
and related types, so that types can be used to
discriminate between ExecutionContexts at compile-time, and so Futures can
declare which ExecutionContext their operations are in.
For Scala 2.12, you must pass -Xsource:2.13
to scalac for methods and
conversions to be automatically found. You must also import
scalaz.syntax.bind._
or similar for Future methods like map
, flatMap
,
and so on.
There are no constraints on the EC
type variable; you need only declare
types you wish to use for it that are sufficient for describing the domains
in which you want ExecutionContexts to be discriminated. These types will
never be instantiated, so you can simply declare that they exist. They can
be totally separate, or have subtyping relationships; any subtyping
relationships they have will be reflected in equivalent subtyping
relationships between the resulting ExecutionContext
s; if you declare
sealed trait Elephant extends Animal
, then automatically
ExecutionContext[Elephant] <: ExecutionContext[Animal]
with scalac
preferring the former when available (because it is "more specific"). They
can even be singleton types, so you might use x.type
to suggest that the
context is associated with the exact value of the x
variable.
If you want to, say, refer to both sc.Future and concurrent.Future in the same file, we recommend importing *the containing package* with an alias rather than renaming each individual class you import. For example,
import com.daml.concurrent._ import scala.{concurrent => sc} // OR import scala.concurrent._ import com.daml.{concurrent => dc}
The exact name isn't important, but you should pick a short one that is sufficiently suggestive for you.
You should always be able to remove the substring Of.Instance.T
from any
inferred type; we strongly suggest doing this for clarity.
Demonstrations of the typing behavior can be found in FutureSpec and
ExecutionContextSpec. This library has no interesting runtime
characteristics; you should think of it as exactly like scala.concurrent
in that regard.