com.thoughtworks.dsl.keywords
Members list
Type members
Classlikes
The base keyword to perform asynchronous IO in domains.task.Tasks.
The base keyword to perform asynchronous IO in domains.task.Tasks.
Attributes
- Example:
The following
readAllis a Task to read file content with the help of AsynchronousIo.ReadFileimport java.nio._, file._, channels._ import com.thoughtworks.dsl.domains.Task import com.thoughtworks.dsl.keywords._ import com.thoughtworks.dsl.keywords.Shift._ import com.thoughtworks.dsl.keywords.AsynchronousIo.ReadFile import scala.collection.mutable.ArrayBuffer import scala.io.Codec def readAll(channel: AsynchronousFileChannel, temporaryBufferSize: Int = 4096): Task[ArrayBuffer[CharBuffer]] = Task { val charBuffers = ArrayBuffer.empty[CharBuffer] val decoder = Codec.UTF8.decoder val byteBuffer = ByteBuffer.allocate(temporaryBufferSize) var position: Long = 0L while (!ReadFile(channel, byteBuffer, position) != -1) { position += byteBuffer.position() byteBuffer.flip() charBuffers += decoder.decode(byteBuffer) byteBuffer.clear() } charBuffers }Tasks created from !-notation can be used infor-comprehension, and other keywords can be used together in the sameforblock. For example, the followingcatfunction contains a singleforblock to concatenate file contents. It asynchronously iterates elementsSeq,ArrayBufferandStringwith the help of keywords.Each, managed native resources with the help of keywords.Using, performs previously createdreadAlltask with the help of keywords.Shift, and finally converts the return type as aTask[Vector[Char]].import com.thoughtworks.dsl._ import com.thoughtworks.dsl.keywords._ import com.thoughtworks.dsl.domains.Task import java.net.URL def cat(paths: Path*) = Each.ToView { for { path <- Each(paths) channel <- Using(AsynchronousFileChannel.open(path)) charBuffers <- Shift(readAll(channel)) charBuffer <- Each(charBuffers) char <- Each(charBuffer.toString) } yield char }.to[Task]Then the
catfunction is used to concatenate files from this project, as shown below:Task.toFuture(Task { val filesToRead = for (fileName <- Seq(".sbtopts", ".scalafmt.conf")) yield { Paths.get(sourcecode.File()).getParent.resolve("../../../../../..").resolve(fileName) } (!Shift(cat(filesToRead: _*))).mkString should be( filesToRead.map { fileToRead => new String(Files.readAllBytes(fileToRead), io.Codec.UTF8.charSet) }.mkString ) })- Companion:
- object
- Source:
- AsynchronousIo.scala
- Graph
- Supertypes
- trait Traitclass Any
- Known subtypes
Attributes
- Companion:
- trait
- Source:
- AsynchronousIo.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- AsynchronousIo.type
Attributes
- Source:
- Await.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Await.type
Attributes
- Source:
- Each.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Each.type
Attributes
- Source:
- Fence.scala
- Graph
- Supertypes
- Self type
- Fence.type
Attributes
- Companion:
- object
- Source:
- FlatMap.scala
- Graph
- Supertypes
Attributes
- Companion:
- class
- Source:
- FlatMap.scala
- Graph
- Supertypes
- Self type
- FlatMap.type
Attributes
- Source:
- Match.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Match.type
Attributes
- Source:
- Monadic.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Monadic.type
Attributes
- Source:
- NoneSafe.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- NoneSafe.type
Attributes
- Source:
- Pure.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Pure.type
Attributes
- Source:
- Return.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Return.type
Attributes
- Source:
- Shift.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Shift.type
Attributes
- Source:
- Suspend.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Suspend.type
Attributes
- Companion:
- object
- Source:
- TryCatch.scala
- Graph
- Supertypes
Attributes
- Companion:
- class
- Source:
- TryCatch.scala
- Graph
- Supertypes
- Self type
- TryCatch.type
Attributes
- Companion:
- object
- Source:
- TryCatchFinally.scala
- Graph
- Supertypes
Attributes
- Companion:
- class
- Source:
- TryCatchFinally.scala
- Graph
- Supertypes
- Self type
- TryCatchFinally.type
Attributes
- Companion:
- object
- Source:
- TryFinally.scala
- Graph
- Supertypes
Attributes
- Companion:
- class
- Source:
- TryFinally.scala
- Graph
- Supertypes
- Self type
- TryFinally.type
Attributes
- Source:
- Typed.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Typed.type
Attributes
- Source:
- Using.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Using.type
Attributes
- Companion:
- object
- Source:
- While.scala
- Graph
- Supertypes
Attributes
- Companion:
- class
- Source:
- While.scala
- Graph
- Supertypes
- Self type
- While.type
Attributes
- Source:
- Yield.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any
- Self type
- Yield.type
Types
Await is a Keyword to extract value from a scala.concurrent.Future.
Await is a Keyword to extract value from a scala.concurrent.Future.
This keyword is available in functions whose return types are
Future, domains.task.Task, or any exception
aware continuations as (_ !! Throwable !! _).
Attributes
- Authors:
杨博 (Yang Bo)
- Example:
Given a Future:
import com.thoughtworks.dsl.macros.Reset.Default.* import scala.concurrent.Future val myFuture40 = Future { 40 }You can Await the Future in another Future
def myFuture42 = *[Future] { !Await(myFuture40) + 2 }A Future can be converted to a domains.task.Task with the help of Await.
import com.thoughtworks.dsl.domains.Task import com.thoughtworks.dsl.keywords.Await val myTask = Task { !Await(myFuture42) }Then a domains.task.Task can be converted back to a scala.concurrent.Future via domains.task.Task.toFuture.
val myAssertionTask = Task { !Shift(myTask) should be(42) } Task.toFuture(myAssertionTask)!Awaitcan be used together withtry/catch/finally.import scala.concurrent.Future import com.thoughtworks.dsl.macros.Reset.Default.* val buffer = new StringBuffer def recoverFuture = Future { buffer.append("Oh") } def exceptionalFuture = Future[StringBuffer] { throw new IllegalStateException("No") } def myFuture = *[Future] { try { !Await(exceptionalFuture) } catch { case e: IllegalStateException => !Await(recoverFuture) buffer.append(' ') buffer.append(e.getMessage) } finally { buffer.append("!") } } myFuture.map(_.toString should be("Oh No!"))Other keywords, including Return or Get, can be used together with Await
import scala.concurrent.Future import com.thoughtworks.dsl.keywords.{Get, Return} import com.thoughtworks.dsl.macros.Reset.Default.* val buffer = new StringBuffer def recoverFuture = Future { buffer.append("Oh") } def exceptionalFuture = Future[StringBuffer] { throw new IllegalStateException("No") } def myFuture = reset[Char => Future[StringBuffer]](!Return { try { !Await(exceptionalFuture) } catch { case e: IllegalStateException => !Await(recoverFuture) buffer.append(!Get[Char]) buffer.append(e.getMessage) } finally { buffer.append("!") } }) myFuture(' ').map(_.toString should be("Oh No!"))- Source:
- Await.scala
Iterates though each element in elements.
Iterates though each element in elements.
Attributes
- Authors:
杨博 (Yang Bo)
- See also:
Dsl.For if you want to use traditional
forcomprehension instead of !-notation.- Example:
Each keywords can be used to calculate cartesian product.
import com.thoughtworks.dsl.macros.Reset.Default.* def cartesianProduct = reset (List(!Each(Array(1, 2, 3)) * !Each(Vector(1, 10, 100, 1000)))) cartesianProduct should be(List(1, 10, 100, 1000, 2, 20, 200, 2000, 3, 30, 300, 3000))- Source:
- Each.scala
A keyword for extracting monadic value from the monadic expression fa.
A keyword for extracting monadic value from the monadic expression fa.
Attributes
- See also:
com.thoughtworks.dsl.domains.cats for using this Monadic keyword with cats.Monad.
com.thoughtworks.dsl.domains.scalaz for using this Monadic keyword with scalaz.Monad.
- Todo:
Monadic should be a scala.AnyVal after https://github.com/scala/bug/issues/10595 is resolved.
- Source:
- Monadic.scala
Attributes
- Source:
- NoneSafe.scala
Attributes
- Source:
- Pure.scala
Put is a Keyword to replace the value of the current context.
Purely functional programming languages usually do not support native first-class mutable variables. In those languages, mutable states can be implemented in state monads.
Put and Get are the Dsl-based replacements of state monads.
We use unary function as the domain of mutable state. The parameter of the unary function can be read from the Get keyword, and changed by the Put keyword.
Attributes
- Authors:
杨博 (Yang Bo)
- See also:
- Example:
The following example creates a function that accepts a string parameter and returns the upper-cased last character of the parameter.
import com.thoughtworks.dsl.macros.Reset.Default.reset def upperCasedLastCharacter = reset[String => Char] { val initialValue = !Get[String] !Put(initialValue.toUpperCase) val upperCased = !Get[String] Function.const(upperCased.last) }For example, given a string of
foo, the upper-cased last character should beO.upperCasedLastCharacter("foo") should be('O')Put and Get support multiple states. The following code creates a formatter that Put parts of content into a
Vector[Any]of string buffers.import com.thoughtworks.dsl.macros.Reset.Default.reset def formatter = reset[Double => Int => Vector[Any] => String] { !Put(!Get[Vector[Any]] :+ "x=") !Put(!Get[Vector[Any]] :+ !Get[Double]) !Put(!Get[Vector[Any]] :+ ",y=") !Put(!Get[Vector[Any]] :+ !Get[Int]) !Return((!Get[Vector[Any]]).mkString) } formatter(0.5)(42)(Vector.empty) should be("x=0.5,y=42")- Source:
- Put.scala
A Dsl.Keyword to early return a lifted value from the enclosing function.
A Dsl.Keyword to early return a lifted value from the enclosing function.
Attributes
- Authors:
杨博 (Yang Bo)
- Source:
- Return.scala
A keyword that extracts the value from a domains.Continuation.
A keyword that extracts the value from a domains.Continuation.
Attributes
- Authors:
杨博 (Yang Bo)
- Note:
This Shift keyword includes special treatment for exception handling and stack safety. Always use
Shift(cont).cpsApply { x => ... }instead ofcont { x => ... }to register a handler for the continuation, otherwise exception might be uncaught or stack might overflow.- Example:
Given a continuation whose type is
Unit !! Throwable !! Int, it is considered as having an exception handler. When an exception is thrown,import scala.util.control.TailCalls.TailRec type !![R, +A] = (A => R) => R val cont: Unit !! Throwable !! Int = _ { if (System.nanoTime() > 0) { throw new Exception("my-exception") } else { 42 } }Then
cpsApplyshould catch the exception:Shift(cont).cpsApply[Unit !! Throwable] { i: Int => (failureHandler: Throwable => Unit) => fail("unreachable code") } { e: Throwable => e.getMessage should be("my-exception") }However,
cont.applydoes not catch the exception:an[Exception] should be thrownBy { cont.apply { i => failureHandler => fail("unreachable code") } { e => e.getMessage should be("my-exception") } }- Source:
- Shift.scala
Attributes
- Source:
- Suspend.scala
A type annotated keyword
This Using keyword automatically manage resources in
scala.concurrent.Future, domains.task.Task, and other asynchronous
domains derived from Future or Task.
This Using keyword automatically manage resources in
scala.concurrent.Future, domains.task.Task, and other asynchronous
domains derived from Future or Task.
Attributes
- Authors:
杨博 (Yang Bo)
- See also:
- Source:
- Using.scala
Attributes
- Authors:
杨博 (Yang Bo)
- See also:
comprehension if you want to use traditional
forcomprehension instead of !-notation.- Example:
This
Yieldkeyword must be put inside a function that returnsSeq[Element]orSeq[Element] !! ..., or it will not compile.import com.thoughtworks.dsl.macros.Reset.Default.* "def f(): Int = !Yield(1)" shouldNot compileYield keywords can be used together with other keywords.
import com.thoughtworks.dsl.macros.Reset.Default.* def gccFlagBuilder(sourceFile: String, includes: String*) = reset[Stream[String]] { !Yield("gcc") !Yield("-c") !Yield(sourceFile) val include = !Each(includes) !Yield("-I") !Yield(include) Stream.empty } gccFlagBuilder("main.c", "lib1/include", "lib2/include") should be(Stream("gcc", "-c", "main.c", "-I", "lib1/include", "-I", "lib2/include"))- Source:
- Yield.scala
Value members
Concrete methods
Attributes
- Source:
- Await.scala
Attributes
- Source:
- Each.scala
Attributes
- Source:
- Monadic.scala
Attributes
- Source:
- NoneSafe.scala
Attributes
- Source:
- Pure.scala
Attributes
- Source:
- Put.scala
Attributes
- Source:
- Return.scala
Attributes
- Source:
- Shift.scala
Attributes
- Source:
- Suspend.scala
Attributes
- Source:
- Typed.scala
Attributes
- Source:
- Using.scala
Attributes
- Source:
- Yield.scala