diff --git a/library/src/scala/concurrent/BatchingExecutor.scala b/library/src/scala/concurrent/BatchingExecutor.scala index 8ca8885980d3..1f86859a5658 100644 --- a/library/src/scala/concurrent/BatchingExecutor.scala +++ b/library/src/scala/concurrent/BatchingExecutor.scala @@ -60,30 +60,38 @@ private[concurrent] object BatchingExecutorStatics { * When you implement this trait for async executors like thread pools, * you're going to need to implement it something like the following: * - * ``` - * final override def submitAsync(runnable: Runnable): Unit = - * super[SuperClass].execute(runnable) // To prevent reentrancy into `execute` + * ```scala sc:compile + * import java.util.concurrent.Executor + * + * final class AsyncBatchingExecutor(delegate: Executor) + * extends ExecutionContextExecutor + * with BatchingExecutor { + * final override def submitForExecution(runnable: Runnable): Unit = + * delegate.execute(runnable) * - * final override def execute(runnable: Runnable): Unit = - * if (runnable.isInstanceOf[Batchable]) // Or other logic - * submitAsyncBatched(runnable) - * else - * submitAsync(runnable) + * final override def execute(runnable: Runnable): Unit = + * if (runnable.isInstanceOf[Batchable]) + * submitAsyncBatched(runnable) + * else + * submitForExecution(runnable) * - * final override def reportFailure(cause: Throwable): Unit = … + * final override def reportFailure(cause: Throwable): Unit = () + * } * ``` * * And if you want to implement if for a sync, trampolining, executor you're * going to implement it something like this: * - * ``` - * final override def submitAsync(runnable: Runnable): Unit = () + * ```scala sc:compile + * final class TrampoliningExecutor extends ExecutionContextExecutor with BatchingExecutor { + * final override def submitForExecution(runnable: Runnable): Unit = () * - * final override def execute(runnable: Runnable): Unit = - * submitSyncBatched(runnable) // You typically will want to batch everything + * final override def execute(runnable: Runnable): Unit = + * submitSyncBatched(runnable) * - * final override def reportFailure(cause: Throwable): Unit = - * ExecutionContext.defaultReporter(cause) // Or choose something more fitting + * final override def reportFailure(cause: Throwable): Unit = + * ExecutionContext.defaultReporter(cause) + * } * ``` */ private[concurrent] trait BatchingExecutor extends Executor { diff --git a/library/src/scala/concurrent/BlockContext.scala b/library/src/scala/concurrent/BlockContext.scala index 675626e3f38b..4bd97a58f466 100644 --- a/library/src/scala/concurrent/BlockContext.scala +++ b/library/src/scala/concurrent/BlockContext.scala @@ -27,7 +27,7 @@ import scala.language.`2.13` * * Typically, you'll want to chain to the previous `BlockContext`, * like this: - * ``` + * ```scala sc:compile * val oldContext = BlockContext.current * val myContext = new BlockContext { * override def blockOn[T](thunk: => T)(implicit permission: CanAwait): T = { diff --git a/library/src/scala/concurrent/ExecutionContext.scala b/library/src/scala/concurrent/ExecutionContext.scala index bfa6d598f61e..5ad8ef448a90 100644 --- a/library/src/scala/concurrent/ExecutionContext.scala +++ b/library/src/scala/concurrent/ExecutionContext.scala @@ -155,7 +155,7 @@ object ExecutionContext { * in case the `opportunistic` field is missing (example below). The resulting `ExecutionContext` has batching * behavior in all Scala 2.13 versions (`global` is batching in 2.13.0-3). * - * ``` + * ```scala sc:compile * implicit val ec: scala.concurrent.ExecutionContext = try { * scala.concurrent.ExecutionContext.getClass * .getDeclaredMethod("opportunistic") @@ -174,19 +174,23 @@ object ExecutionContext { * 1. Writing a Scala `object` in the `scala` package (example below). * 1. Writing a Java source file. This works because `private[scala]` is emitted as `public` in Java bytecode. * - * ``` - * // Option 1 + * ```scala sc:compile + * import scala.language.reflectiveCalls + * + * type ExecutionContextCompanionApi = AnyRef { + * def opportunistic: scala.concurrent.ExecutionContextExecutor + * } + * * implicit val ec: scala.concurrent.ExecutionContext = - * (scala.concurrent.ExecutionContext: - * {def opportunistic: scala.concurrent.ExecutionContextExecutor} - * ).opportunistic - * - * // Option 2 - * package scala { - * object OpportunisticEC { - * implicit val ec: scala.concurrent.ExecutionContext = - * scala.concurrent.ExecutionContext.opportunistic - * } + * scala.concurrent.ExecutionContext + * .asInstanceOf[ExecutionContextCompanionApi] + * .opportunistic + * ``` + * + * ```scala sc:compile + * object OpportunisticEC { + * implicit val ec: scala.concurrent.ExecutionContext = + * scala.concurrent.ExecutionContext.opportunistic * } * ``` * @@ -252,7 +256,7 @@ object ExecutionContext { * If it is guaranteed that none of the executed tasks are blocking, a single-threaded `ExecutorService` * can be used to create an `ExecutionContext` as follows: * - * ``` + * ```scala sc:compile * import java.util.concurrent.Executors * val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor()) * ``` diff --git a/library/src/scala/concurrent/Future.scala b/library/src/scala/concurrent/Future.scala index 9aa1ddbd521b..b80f3e492649 100644 --- a/library/src/scala/concurrent/Future.scala +++ b/library/src/scala/concurrent/Future.scala @@ -31,7 +31,7 @@ import scala.concurrent.impl.Promise.DefaultPromise * Computations are executed using an `ExecutionContext`, which is usually supplied implicitly, * and which is commonly backed by a thread pool. * - * ``` + * ```scala sc:compile * import ExecutionContext.Implicits.global * val s = "Hello" * val f: Future[String] = Future { @@ -79,7 +79,8 @@ import scala.concurrent.impl.Promise.DefaultPromise * @define forComprehensionExamples * Example: * - * ``` + * ```scala sc:compile + * import ExecutionContext.Implicits.global * val f = Future { 5 } * val g = Future { 3 } * val h = for { @@ -90,7 +91,10 @@ import scala.concurrent.impl.Promise.DefaultPromise * * is translated to: * - * ``` + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * val f = Future { 5 } + * val g = Future { 3 } * f flatMap { (x: Int) => g map { (y: Int) => x + y } } * ``` * @@ -237,9 +241,10 @@ trait Future[+T] extends Awaitable[T] { * * Example: * - * ``` + * ```scala sc:compile + * import ExecutionContext.Implicits.global * val f = Future { "The future" } - * val g = f map { x: String => x + " is now!" } + * val g = f.map { (x: String) => x + " is now!" } * ``` * * Note that a for comprehension involving a `Future` @@ -291,7 +296,9 @@ trait Future[+T] extends Awaitable[T] { * If the current future fails, then the resulting future also fails. * * Example: - * ``` + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * import scala.concurrent.duration.Duration * val f = Future { 5 } * val g = f filter { _ % 2 == 1 } * val h = f filter { _ % 2 == 0 } @@ -329,7 +336,9 @@ trait Future[+T] extends Awaitable[T] { * If the current future fails, then the resulting future also fails. * * Example: - * ``` + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * import scala.concurrent.duration.Duration * val f = Future { -5 } * val g = f collect { * case x if x < 0 => -x @@ -361,10 +370,11 @@ trait Future[+T] extends Awaitable[T] { * * Example: * - * ``` - * Future (6 / 0) recover { case e: ArithmeticException => 0 } // result: 0 - * Future (6 / 0) recover { case e: NotFoundException => 0 } // result: exception - * Future (6 / 2) recover { case e: ArithmeticException => 0 } // result: 3 + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * Future(6 / 0).recover { case _: ArithmeticException => 0 } // result: 0 + * Future(6 / 0).recover { case _: NoSuchElementException => 0 } // result: exception + * Future(6 / 2).recover { case _: ArithmeticException => 0 } // result: 3 * ``` * * @tparam U the type of the returned `Future` @@ -384,9 +394,10 @@ trait Future[+T] extends Awaitable[T] { * * Example: * - * ``` + * ```scala sc:compile + * import ExecutionContext.Implicits.global * val f = Future { Int.MaxValue } - * Future (6 / 0) recoverWith { case e: ArithmeticException => f } // result: Int.MaxValue + * Future(6 / 0).recoverWith { case _: ArithmeticException => f } // result: Int.MaxValue * ``` * * @tparam U the type of the returned `Future` @@ -454,7 +465,8 @@ trait Future[+T] extends Awaitable[T] { * Using this method will not cause concurrent programs to become nondeterministic. * * Example: - * ``` + * ```scala sc:compile + * import ExecutionContext.Implicits.global * val f = Future { throw new RuntimeException("failed") } * val g = Future { 5 } * val h = f fallbackTo g @@ -508,7 +520,9 @@ trait Future[+T] extends Awaitable[T] { * * The following example prints out `5`: * - * ``` + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * import scala.util.{Failure, Success} * val f = Future { 5 } * f andThen { * case r => throw new RuntimeException("runtime exception") @@ -689,10 +703,12 @@ object Future { * * The following expressions are equivalent: * - * ``` - * val f1 = Future(expr) - * val f2 = Future.unit.map(_ => expr) - * val f3 = Future.unit.transform(_ => Success(expr)) + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * import scala.util.Success + * val f1 = Future(1 + 1) + * val f2 = Future.unit.map(_ => 1 + 1) + * val f3 = Future.unit.transform(_ => Success(1 + 1)) * ``` * * The result becomes available once the asynchronous computation is completed. @@ -709,10 +725,11 @@ object Future { * * The following expressions are semantically equivalent: * - * ``` - * val f1 = Future(expr).flatten - * val f2 = Future.delegate(expr) - * val f3 = Future.unit.flatMap(_ => expr) + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * val f1 = Future(Future.successful(1 + 1)).flatten + * val f2 = Future.delegate(Future.successful(1 + 1)) + * val f3 = Future.unit.flatMap(_ => Future.successful(1 + 1)) * ``` * * The result becomes available once the resulting Future of the asynchronous computation is completed. @@ -805,8 +822,10 @@ object Future { * or the result of the fold. * * Example: - * ``` - * val futureSum = Future.foldLeft(futures)(0)(_ + _) + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * val futures = List(Future.successful(1), Future.successful(2), Future.successful(3)) + * val futureSum = Future.foldLeft(futures)(0)(_ + _) * ``` * * @tparam T the type of the value of the input Futures @@ -829,8 +848,10 @@ object Future { * or the result of the fold. * * Example: - * ``` - * val futureSum = Future.fold(futures)(0)(_ + _) + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * val futures = List(Future.successful(1), Future.successful(2), Future.successful(3)) + * val futureSum = Future.fold(futures)(0)(_ + _) * ``` * * @tparam T the type of the value of the input Futures @@ -850,8 +871,10 @@ object Future { * where the fold-zero is the result value of the first `Future` in the collection. * * Example: - * ``` - * val futureSum = Future.reduce(futures)(_ + _) + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * val futures = List(Future.successful(1), Future.successful(2), Future.successful(3)) + * val futureSum = Future.reduce(futures)(_ + _) * ``` * @tparam T the type of the value of the input Futures * @tparam R the type of the value of the returned `Future` @@ -869,8 +892,10 @@ object Future { * where the zero is the result value of the first `Future`. * * Example: - * ``` - * val futureSum = Future.reduceLeft(futures)(_ + _) + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * val futures = List(Future.successful(1), Future.successful(2), Future.successful(3)) + * val futureSum = Future.reduceLeft(futures)(_ + _) * ``` * @tparam T the type of the value of the input Futures * @tparam R the type of the value of the returned `Future` @@ -889,8 +914,11 @@ object Future { * This is useful for performing a parallel map. For example, to apply a function to all items of a list * in parallel: * - * ``` - * val myFutureList = Future.traverse(myList)(x => Future(myFunc(x))) + * ```scala sc:compile + * import ExecutionContext.Implicits.global + * val myList = List(1, 2, 3) + * def myFunc(x: Int): Int = x + 1 + * val myFutureList = Future.traverse(myList)(x => Future(myFunc(x))) * ``` * @tparam A the type of the value inside the Futures in the collection * @tparam B the type of the value of the returned `Future` diff --git a/library/src/scala/concurrent/duration/Deadline.scala b/library/src/scala/concurrent/duration/Deadline.scala index cde7904f46eb..a079cf156c32 100644 --- a/library/src/scala/concurrent/duration/Deadline.scala +++ b/library/src/scala/concurrent/duration/Deadline.scala @@ -17,8 +17,8 @@ import scala.language.`2.13` /** This class stores a deadline, as obtained via `Deadline.now` or the * duration DSL: * - * ``` - * import scala.concurrent.duration._ + * ```scala sc:compile + * import scala.concurrent.duration.* * 3.seconds.fromNow * ``` * diff --git a/library/src/scala/concurrent/duration/Duration.scala b/library/src/scala/concurrent/duration/Duration.scala index 80fd8567af1b..815266d20bc3 100644 --- a/library/src/scala/concurrent/duration/Duration.scala +++ b/library/src/scala/concurrent/duration/Duration.scala @@ -323,11 +323,11 @@ object Duration { * *

* Examples: - * ``` - * import scala.concurrent.duration._ + * ```scala sc:compile + * import scala.concurrent.duration.* * * val duration = Duration(100, MILLISECONDS) - * val duration = Duration(100, "millis") + * val sameDuration = Duration(100, "millis") * * duration.toNanos * duration < 1.second @@ -338,8 +338,8 @@ object Duration { * *

* Implicits are also provided for Int, Long and Double. Example usage: - * ``` - * import scala.concurrent.duration._ + * ```scala sc:compile + * import scala.concurrent.duration.* * * val duration = 100.millis * ``` @@ -347,7 +347,9 @@ object Duration { * ***The DSL provided by the implicit conversions always allows construction of finite durations, even for infinite Double inputs; use Duration.Inf instead.*** * * Extractors, parsing and arithmetic are also included: - * ``` + * ```scala sc:compile + * import scala.concurrent.duration.* + * import scala.language.postfixOps * val d = Duration("1.2 µs") * val Duration(length, unit) = 5 millis * val d2 = d * 2.5 @@ -567,7 +569,8 @@ sealed abstract class Duration extends Serializable with Ordered[Duration] { /** Returns duration which is equal to this duration but with a coarsest Unit, or self in case it is already the coarsest Unit *

* Examples: - * ``` + * ```scala sc:compile + * import scala.concurrent.duration.* * Duration(60, MINUTES).toCoarsest // Duration(1, HOURS) * Duration(1000, MILLISECONDS).toCoarsest // Duration(1, SECONDS) * Duration(48, HOURS).toCoarsest // Duration(2, DAYS) diff --git a/library/src/scala/concurrent/duration/package.scala b/library/src/scala/concurrent/duration/package.scala index 8eafd0f7f8bc..4111462c77f0 100644 --- a/library/src/scala/concurrent/duration/package.scala +++ b/library/src/scala/concurrent/duration/package.scala @@ -20,12 +20,12 @@ package object duration { * This object can be used as closing token if you prefer dot-less style but do not want * to enable language.postfixOps: * - * ``` - * import scala.concurrent.duration._ + * ```scala sc:compile + * import scala.concurrent.duration.* * * val duration = 2 seconds span * ``` - + */ object span @@ -33,12 +33,12 @@ package object duration { * This object can be used as closing token for declaring a deadline at some future point * in time: * - * ``` - * import scala.concurrent.duration._ + * ```scala sc:compile + * import scala.concurrent.duration.* * * val deadline = 3 seconds fromNow * ``` - + */ object fromNow diff --git a/library/src/scala/concurrent/package.scala b/library/src/scala/concurrent/package.scala index 031bed756584..fe0f47ac0a80 100644 --- a/library/src/scala/concurrent/package.scala +++ b/library/src/scala/concurrent/package.scala @@ -30,7 +30,7 @@ import scala.util.Try * When working with Futures, you will often find that importing the whole concurrent * package is convenient: * - * ``` + * ```scala sc:compile * import scala.concurrent._ * ``` * @@ -40,10 +40,12 @@ import scala.util.Try * If the code in question is a class or method definition, and no `ExecutionContext` is available, * request one from the caller by adding an implicit parameter list: * - * ``` - * def myMethod(myParam: MyType)(implicit ec: ExecutionContext) = … - * //Or - * class MyClass(myParam: MyType)(implicit ec: ExecutionContext) { … } + * ```scala sc:compile + * def myMethod(myParam: Int)(implicit ec: ExecutionContext): Int = myParam + 1 + * // Or + * class MyClass(myParam: Int)(implicit ec: ExecutionContext) { + * def doubled: Int = myParam * 2 + * } * ``` * * This allows the caller of the method, or creator of the instance of the class, to decide which @@ -51,7 +53,7 @@ import scala.util.Try * * For typical REPL usage and experimentation, importing the global `ExecutionContext` is often desired. * - * ``` + * ```scala sc:compile * import scala.concurrent.ExecutionContext.Implicits.global * ``` * @@ -60,8 +62,8 @@ import scala.util.Try * Operations often require a duration to be specified. A duration DSL is available * to make defining these easier: * - * ``` - * import scala.concurrent.duration._ + * ```scala sc:compile + * import scala.concurrent.duration.* * val d: Duration = 10.seconds * ``` * @@ -72,13 +74,12 @@ import scala.util.Try * without blocking the current thread. In order to create the Future you will need * either an implicit or explicit ExecutionContext to be provided: * - * ``` - * import scala.concurrent._ + * ```scala sc:compile + * import scala.concurrent.* * import ExecutionContext.Implicits.global // implicit execution context * * val firstZebra: Future[Int] = Future { - * val words = Files.readAllLines("/etc/dictionaries-common/words").asScala - * words.indexOfSlice("zebra") + * "aardvark zebra".indexOf("zebra") * } * ``` * @@ -86,8 +87,10 @@ import scala.util.Try * * Although blocking is possible in order to await results (with a mandatory timeout duration): * - * ``` - * import scala.concurrent.duration._ + * ```scala sc:compile + * import scala.concurrent.* + * import scala.concurrent.duration.* + * val firstZebra = Future.successful(9) * Await.result(firstZebra, 10.seconds) * ``` * @@ -96,14 +99,18 @@ import scala.util.Try * potential deadlocks and improve performance. Instead, use callbacks or combinators to * remain in the future domain: * - * ``` + * ```scala sc:compile + * import scala.concurrent.* + * import scala.concurrent.ExecutionContext.Implicits.global + * val firstAardvark = Future.successful(0) + * val firstZebra = Future.successful(600001) * val animalRange: Future[Int] = for { * aardvark <- firstAardvark * zebra <- firstZebra * } yield zebra - aardvark * - * animalRange.onSuccess { - * case x if x > 500000 => println("It's a long way from Aardvark to Zebra") + * animalRange.foreach { x => + * if (x > 500000) println("It's a long way from Aardvark to Zebra") * } * ``` */