Skip to content

Commit

Permalink
Merge pull request #97 from VirtusLab/parallelize-rename
Browse files Browse the repository at this point in the history
Add parallelize as the main exported function, deprecate ado
  • Loading branch information
KacperFKorban authored Apr 3, 2024
2 parents 99f0fe7 + 975af76 commit 07b3cc3
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 132 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import avocado.*
import avocado.instances.cats.given

val run: IO[Int] =
ado {
parallelize {
for {
a <- doStuff1
b <- doStuff2(a)
Expand All @@ -33,7 +33,7 @@ for {

`avocADO` is a small library that allows for automatic rewriting of `for` comprehensions to their parallel versions.

The name `avocADO` is a pun on the most important function exposed by the library - `ado` (name taken from Haskell's language extension `ApplicativeDo`).
The name `avocADO` is a pun on the function that is the inspiration for this library - `ado` from Haskell's language extension `ApplicativeDo`.

## Usage (with build tools)

Expand Down Expand Up @@ -61,19 +61,19 @@ libraryDependencies ++= Seq(

## Usage (in code)

All you need to do in order to use `avocADO` is to import the `ado` function and an `AvocADO` instance for your effect system. i.e.
All you need to do in order to use `avocADO` is to import the `parallelize` function and an `AvocADO` instance for your effect system. i.e.
```scala
import avocado.* // This line exposes the `ado` function - entrypoint of the library
import avocado.* // This line exposes the `parallelize` function - entrypoint of the library
// You should choose one of the following imports depending on your effect system of choice
import avocado.instances.cats.given
import avocado.instances.zio2.given
import avocado.instances.zio1.given
import avocado.instances.zioquery.given
```

And that's it! All that's left is to wrap the `for`-comprehensions that you want to parallelize with a call to `ado` an watch your program run in parallel! Like so:
And that's it! All that's left is to wrap the `for`-comprehensions that you want to parallelize with a call to `parallelize` an watch your program run in parallel! Like so:
```scala
ado {
parallelize {
for {
...
} yield ...
Expand Down
33 changes: 33 additions & 0 deletions avocADO/src/main/scala/ado.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,38 @@ package avocado

import macros.*

/**
* Transforms the provided for-comprehension to it's parallel version.
* Example usage:
* ```scala
* parallelize {
* for {
* a <- doStuff1
* b <- doStuff2(a)
* c <- doStuff3
* d <- doStuff4(a)
* } yield combine(a, b, c, d)
* }
* ```
*
* The above code will be transformed to code essentially equivalent to:
* ```scala
* for {
* a <- doStuff1
* (b, c, d) <- doStuff2(a).zip(doStuff3).zip(doStuff4(a))
* } yield combine(a, b, c, d)
* ```
*
* The transformed code will use the provided implicit [[avocado.AvocADO]]
* instance for method calls such as `map`, `flatMap` and `zip`. Potential for
* parallelism is introduced in places where `zip` calls are used. So in order
* to utilize this method in a sensible way, [[avocado.AvocADO.zip]] should
* initialize parallel calls. Though this method should also be safe for
* sequential operations.
*/
inline def parallelize[F[_], A](inline comp: F[A])(using ap: AvocADO[F]): F[A] =
${ macros.adoImpl[F, A]('comp, 'ap) }

/**
* Transforms the provided for-comprehension to it's parallel version.
* Example usage:
Expand Down Expand Up @@ -31,6 +63,7 @@ import macros.*
* initialize parallel calls. Though this method should also be safe for
* sequential operations.
*/
@deprecated("Use parallelize instead", "0.2.0")
inline def ado[F[_], A](inline comp: F[A])(using ap: AvocADO[F]): F[A] =
${ macros.adoImpl[F, A]('comp, 'ap) }

Expand Down
2 changes: 1 addition & 1 deletion avocADO/src/main/scala/macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ private[avocado] object macros {
}

def throwGenericError(): Nothing =
report.errorAndAbort("Oopsie, wrong argument passed to ado!")
report.errorAndAbort("Oopsie, wrong argument passed to parallelize!")

private def supportedRewriteMethod(name: String): Boolean =
List("flatMap", "map").contains(name)
Expand Down
4 changes: 2 additions & 2 deletions avocADO/src/test/scala/ExplicitPipelineTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ExplicitPipelineTests extends munit.FunSuite {
}

test("handwritten pipeline 1") {
val res = ado {
val res = parallelize {
Some(1).flatMap { a =>
Some(2).map { b =>
a + b
Expand All @@ -23,7 +23,7 @@ class ExplicitPipelineTests extends munit.FunSuite {
}

test("handwritten pipeline 2") {
val res = ado {
val res = parallelize {
Some(1).flatMap { a =>
Some(2).flatMap { b =>
Some(a + b)
Expand Down
44 changes: 22 additions & 22 deletions avocADO/src/test/scala/OptionTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 1") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
b <- Some(2)
Expand All @@ -22,7 +22,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 2") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
b <- Some(2)
Expand All @@ -33,7 +33,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 3") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
b <- Some(2)
Expand All @@ -44,7 +44,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 4") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
b <- Some(2)
Expand All @@ -56,7 +56,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 5") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
b <- Some(2)
Expand All @@ -69,7 +69,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 6") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
b <- Some(2)
Expand All @@ -81,7 +81,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 7") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
aa <- None
Expand All @@ -93,7 +93,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 8") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
} yield a
Expand All @@ -102,7 +102,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 9") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
a <- Some(a)
Expand All @@ -113,7 +113,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 10") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
b <- Some(a + 2)
Expand All @@ -124,7 +124,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 11") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
b <- Some(a + 2)
Expand All @@ -135,7 +135,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 12") {
val res = ado {
val res = parallelize {
for {
_ <- Option(null)
xd <- Option {
Expand All @@ -147,7 +147,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 13") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
a <- Some(2)
Expand All @@ -158,7 +158,7 @@ class OptionTests extends munit.FunSuite {

test("option comprehension 14") {
def getImplicit(using i: Int): Option[Int] = Some(i)
val res = ado {
val res = parallelize {
for {
given Int <- Some(2)
b <- getImplicit
Expand All @@ -169,7 +169,7 @@ class OptionTests extends munit.FunSuite {

test("option comprehension 15") {
def getImplicit(using i: Int): Option[Int] = Some(i)
val res = ado {
val res = parallelize {
for {
a <- Some(2)
given Int = 1
Expand All @@ -180,7 +180,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 16") {
val res = ado {
val res = parallelize {
for {
_ <- Some(2)
b = 1
Expand All @@ -191,7 +191,7 @@ class OptionTests extends munit.FunSuite {

test("option comprehension 17") {
def getImplicit(using i: Int): Option[Int] = Some(i)
val res = ado {
val res = parallelize {
for {
_ <- Some(2)
given Int = 1
Expand All @@ -203,7 +203,7 @@ class OptionTests extends munit.FunSuite {


test("option comprehension 18") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
(b: Int) = 2
Expand All @@ -214,7 +214,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 19") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
_ <- Some(2)
Expand All @@ -225,7 +225,7 @@ class OptionTests extends munit.FunSuite {
}

test("option comprehension 20") {
val res = ado {
val res = parallelize {
for {
a <- Some(1)
_ <- Some(2)
Expand All @@ -237,7 +237,7 @@ class OptionTests extends munit.FunSuite {

test("option comprehension 21") {
case class C(i: Int, j: Int)
val res = ado {
val res = parallelize {
for {
a <- Some(1)
_ <- Some(2)
Expand All @@ -249,7 +249,7 @@ class OptionTests extends munit.FunSuite {

test("option comprehension 22") {
case class C(i: Int*)
val res = ado {
val res = parallelize {
for {
a <- Some(1)
_ <- Some(2)
Expand Down
6 changes: 3 additions & 3 deletions avocADO/src/test/scalajvm/FutureTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class FutureTests extends munit.FunSuite {

testWithTimeLimit("Future comprehension 1", 900) {
def wait = Future(Thread.sleep(500))
ado {
parallelize {
for {
a <- Future(1)
} yield a
Expand All @@ -30,7 +30,7 @@ class FutureTests extends munit.FunSuite {

testWithTimeLimit("Future comprehension 2", 900) {
def wait = Future(Thread.sleep(500))
ado {
parallelize {
for {
a <- wait.map(_ => 1)
b <- wait.map(_ => 2)
Expand All @@ -40,7 +40,7 @@ class FutureTests extends munit.FunSuite {

testWithTimeLimit("Future comprehension 3", 1400) {
def wait = Future(Thread.sleep(500))
ado {
parallelize {
for {
a <- wait.map(_ => 1)
b <- wait.map(_ => 2)
Expand Down
Loading

0 comments on commit 07b3cc3

Please sign in to comment.