Skip to content

Commit e0f69e7

Browse files
authored
Merge pull request #566 from Atry/Enable-AtomicThenDerivedThenComposed
Enable Searching.AtomicThenStackSafeDerivedThenComposedThenStackUnsafeDerived by default
2 parents 95dc2aa + a709aff commit e0f69e7

File tree

25 files changed

+737
-466
lines changed
  • Dsl/src/main/scala/com/thoughtworks/dsl
  • domains-Task/.jvm/src/test/scala/com/thoughtworks/dsl/domains
  • domains-scalaz/src/main/scala/com/thoughtworks/dsl/domains
  • keywords-AsynchronousIo/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Await
  • keywords-Each/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-FlatMap/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Get/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-If/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Match/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-NoneSafe/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Pure/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Put/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Return/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Shift/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Suspend/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-TryCatchFinally/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-TryCatch/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-TryFinally/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Typed/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Using/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-While/src/main/scala/com/thoughtworks/dsl/keywords
  • keywords-Yield/src/main/scala/com/thoughtworks/dsl/keywords
  • reset/src/main/scala/com/thoughtworks/dsl

25 files changed

+737
-466
lines changed

Dsl/src/main/scala/com/thoughtworks/dsl/Dsl.scala

Lines changed: 386 additions & 147 deletions
Large diffs are not rendered by default.

domains-Task/.jvm/src/test/scala/com/thoughtworks/dsl/domains/RaiiSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ final class RaiiSpec extends AnyFreeSpec with Matchers {
1616
@inline
1717
private def jvmCatch[Domain](eh: => Domain !! Throwable)(
1818
failureHandler: Throwable => Domain
19-
)(implicit shiftDsl: Dsl[Shift[Domain, Throwable], Domain, Throwable]): Domain = {
19+
)(implicit shiftDsl: Dsl.Searching[Shift[Domain, Throwable], Domain, Throwable]): Domain = {
2020
val protectedContinuation: Domain !! Throwable =
2121
try {
2222
eh
2323
} catch {
2424
case NonFatal(e) =>
2525
return failureHandler(e)
2626
}
27-
shiftDsl.cpsApply(Shift(protectedContinuation), failureHandler)
27+
shiftDsl(Shift(protectedContinuation), failureHandler)
2828
}
2929

3030
/** Exit the current scope then hang up

domains-scalaz/src/main/scala/com/thoughtworks/dsl/domains/scalaz.scala

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -192,42 +192,44 @@ object scalaz {
192192
): Dsl.Lift.OneStep[A, F[A]] =
193193
applicative.pure
194194

195-
implicit def scalazMonadTransformerDsl1[F[_[_], _], H[_], G[_], A, B](implicit
195+
given [F[_[_], _], H[_], G[_], A, B](using
196196
monadTrans: MonadTrans[F],
197197
rest: ScalazTransformerDsl[H, G, A, B]
198-
): ScalazTransformerDsl[H, [X] =>> F[G, X], A, B] =
199-
new ScalazTransformerDsl[H, [X] =>> F[G, X], A, B] {
198+
): Dsl.Atomic[Monadic[H[A]], F[G, B], A] =
199+
Dsl.Atomic(new ScalazTransformerDsl[H, [X] =>> F[G, X], A, B] {
200200

201201
def monad: Monad[[X] =>> F[G, X]] = monadTrans(rest.monad)
202202

203203
def lift(fa: H[A]): F[G, A] = monadTrans.liftM(rest.lift(fa))(rest.monad)
204204

205-
}
205+
})
206206

207-
implicit def scalazMonadTransformerDsl0[F[_[_], _], G[_], A, B](implicit
207+
given [F[_[_], _], G[_], A, B](using
208208
monadTrans: MonadTrans[F],
209209
monad0: Monad[G]
210-
): ScalazTransformerDsl[G, [X] =>> F[G, X], A, B] =
211-
new ScalazTransformerDsl[G, [X] =>> F[G, X], A, B] {
210+
): Dsl.Atomic[Monadic[G[A]], F[G, B], A] =
211+
Dsl.Atomic(new ScalazTransformerDsl[G, [X] =>> F[G, X], A, B] {
212212
def monad = monadTrans(monad0)
213213

214214
def lift(fa: G[A]): F[G, A] = monadTrans.liftM(fa)
215215

216-
}
216+
})
217217

218-
implicit def scalazMonadicDsl[F[_], A, B](implicit bind: Bind[F]): Dsl[Monadic[F[A]], F[B], A] =
219-
new Dsl[Monadic[F[A]], F[B], A] {
220-
def cpsApply(keyword: Monadic[F[A]], handler: A => F[B]): F[B] = {
218+
given [F[_], A, B](using
219+
bind: Bind[F]
220+
): Dsl.Atomic[Monadic[F[A]], F[B], A] =
221+
Dsl.Atomic[Monadic[F[A]], F[B], A] {
222+
(keyword: Monadic[F[A]], handler: A => F[B]) =>
221223
bind.bind(Monadic.apply.flip(keyword))(handler)
222-
}
223224
}
224225

225-
abstract class ScalazTransformerDsl[F[_], G[_], A, B] extends Dsl[Monadic[F[A]], G[B], A] {
226+
abstract class ScalazTransformerDsl[F[_], G[_], A, B]
227+
extends ((Monadic[F[A]], A => G[B]) => G[B]) {
226228
def monad: Monad[G]
227229

228230
def lift(fa: F[A]): G[A]
229231

230-
final def cpsApply(keyword: Monadic[F[A]], handler: A => G[B]): G[B] = {
232+
final def apply(keyword: Monadic[F[A]], handler: A => G[B]): G[B] = {
231233
monad.bind(lift(Monadic.apply.flip(keyword)))(handler)
232234
}
233235

keywords-AsynchronousIo/src/main/scala/com/thoughtworks/dsl/keywords/AsynchronousIo.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,9 @@ object AsynchronousIo {
167167
}
168168
}
169169

170-
implicit def asynchronousIoDsl[Value]: Dsl[AsynchronousIo[Value], Unit !! Throwable, Value] = { (keyword, handler) =>
171-
keyword.start(_, completionHandler(handler))
172-
}
170+
given [Value]: Dsl.Atomic[AsynchronousIo[Value], Unit !! Throwable, Value] =
171+
Dsl.Atomic { (keyword, handler) =>
172+
keyword.start(_, completionHandler(handler))
173+
}
173174

174175
}

keywords-Await/.js/src/main/scala/com/thoughtworks/dsl/keywords/AwaitJS.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ private trait AwaitJS { this: Await.type =>
1212
given [PromiseResult]
1313
: Dsl.IsKeyword[Await[js.Promise[PromiseResult]], PromiseResult] with {}
1414

15-
given [JsPromiseResult, That]: Dsl[Await[js.Promise[JsPromiseResult]], js.Promise[That], JsPromiseResult] =
16-
Await.apply.liftCo[[X] =>> Dsl[X, js.Promise[That], JsPromiseResult]](_ `then` _)
15+
given [JsPromiseResult, That]: Dsl.Atomic[Await[js.Promise[JsPromiseResult]], js.Promise[That], JsPromiseResult] =
16+
Await.apply.liftCo[[X] =>> Dsl.Atomic[X, js.Promise[That], JsPromiseResult]](Dsl.Atomic(_ `then` _))
1717

18-
given [JsPromiseResult, That](using ExecutionContext): Dsl[Await[js.Promise[JsPromiseResult]], Future[That], JsPromiseResult] =
19-
Await.apply.liftCo[[X] =>> Dsl[X, Future[That], JsPromiseResult]] { (promise, handler) =>
18+
given [JsPromiseResult, That](using ExecutionContext): Dsl.Atomic[Await[js.Promise[JsPromiseResult]], Future[That], JsPromiseResult] =
19+
Await.apply.liftCo[[X] =>> Dsl.Atomic[X, Future[That], JsPromiseResult]](Dsl.Atomic { (promise, handler) =>
2020
promise.toFuture.flatMap(handler)
21-
}
21+
})
2222

2323
extension [FA, A](inline fa: FA)(using
2424
inline notKeyword: util.NotGiven[

keywords-Await/src/main/scala/com/thoughtworks/dsl/keywords/Await.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,17 @@ object Await extends AwaitJS {
120120

121121
given [FutureResult, That](using
122122
ExecutionContext
123-
): Dsl[Await[Future[FutureResult]], Future[That], FutureResult] =
124-
_ flatMap _
123+
): Dsl.Atomic[Await[Future[FutureResult]], Future[That], FutureResult] = Dsl.Atomic(
124+
_ flatMap _)
125125

126126
// // TODO:
127127
// implicit def tailRecContinuationAwaitDsl[Value](implicit
128128
// executionContext: ExecutionContext
129-
// ): Dsl[Await[Value], TailRec[Unit] !! Throwable, Value]
129+
// ): Dsl.Atomic[Await[Value], TailRec[Unit] !! Throwable, Value]
130130

131131
given [Value](using
132132
ExecutionContext
133-
): Dsl[Await[Future[Value]], Unit !! Throwable, Value] = {
133+
): Dsl.Atomic[Await[Future[Value]], Unit !! Throwable, Value] = Dsl.Atomic {
134134
(keyword: Await[Future[Value]], handler: Value => Unit !! Throwable) =>
135135
!!.fromTryContinuation[Unit, Value](keyword.onComplete)(handler)
136136
}

keywords-Each/src/main/scala/com/thoughtworks/dsl/keywords/Each.scala

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ object Each {
4545
Collection,
4646
Domain
4747
](using
48-
toViewDsl: Dsl.PolyCont[Each.ToView[ForYield], Domain, View[Element]]
49-
): Dsl.PolyCont[
48+
toViewDsl: Dsl.Searching[Each.ToView[ForYield], Domain, View[Element]]
49+
): Dsl.Composed[
5050
Each.To[ForYield, Element, Collection],
5151
Domain,
5252
Collection
53-
] = { case (keyword, handler) =>
53+
] = Dsl.Composed { (keyword, handler) =>
5454
val factory = keyword.factory
55-
toViewDsl.cpsApply(
55+
toViewDsl(
5656
ToView(keyword.forYield),
5757
{ view => handler(view.to(factory)) }
5858
)
@@ -364,14 +364,14 @@ object Each {
364364
Keyword,
365365
Value
366366
],
367-
polyCont: Dsl.PolyCont[
367+
polyCont: Dsl.Searching[
368368
Keyword,
369369
Domain,
370370
Value
371371
]
372-
): Dsl.PolyCont[Each.ToView[Comprehension], Domain, Value] = {
372+
): Dsl.Composed[Each.ToView[Comprehension], Domain, Value] = Dsl.Composed {
373373
(as, handler) =>
374-
polyCont.cpsApply(toKeyword(as), handler)
374+
polyCont(toKeyword(as), handler)
375375
}
376376
}
377377

@@ -412,12 +412,12 @@ object Each {
412412
MappedValue
413413
],
414414
factory: Factory[MappedElement, MappedValue],
415-
blockDsl: Dsl.PolyCont[MappedKeyword, Domain, MappedValue]
416-
): Dsl.PolyCont[
415+
blockDsl: Dsl.Searching[MappedKeyword, Domain, MappedValue]
416+
): Dsl.Composed[
417417
FlatMap[Each[Element], MappedKeyword],
418418
Domain,
419419
MappedValue
420-
] = {
420+
] = Dsl.Composed {
421421
case (
422422
FlatMap(sourceCollection, flatMapper: (Element @unchecked => MappedKeyword)),
423423
handler
@@ -428,7 +428,7 @@ object Each {
428428
): Domain = {
429429
seqOps.headOption match {
430430
case Some(head) =>
431-
blockDsl.cpsApply(
431+
blockDsl(
432432
flatMapper(head),
433433
{ mappedHead =>
434434
loop(
@@ -456,12 +456,12 @@ object Each {
456456
MappedKeyword,
457457
Domain
458458
](using
459-
blockDsl: Dsl.PolyCont[MappedKeyword, Domain, Unit]
460-
): Dsl.PolyCont[
459+
blockDsl: Dsl.Searching[MappedKeyword, Domain, Unit]
460+
): Dsl.Composed[
461461
FlatMap[Each[Element], MappedKeyword],
462462
Domain,
463463
Unit
464-
] = {
464+
] = Dsl.Composed {
465465
case (
466466
FlatMap(sourceCollection, flatMapper: (Element @unchecked => MappedKeyword)),
467467
handler
@@ -472,7 +472,7 @@ object Each {
472472
): Domain = {
473473
seqOps.headOption match {
474474
case Some(head) =>
475-
blockDsl.cpsApply(
475+
blockDsl(
476476
flatMapper(head),
477477
{ mappedHead =>
478478
loop(

keywords-FlatMap/src/main/scala/com/thoughtworks/dsl/keywords/FlatMap.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@ object FlatMap {
2222
MappedValue,
2323
Domain
2424
](using
25-
upstreamDsl: Dsl.PolyCont[Upstream, Domain, UpstreamValue],
26-
nestedDsl: Dsl.PolyCont[Mapped, Domain, MappedValue]
27-
): Dsl.PolyCont[FlatMap[Upstream, Mapped], Domain, MappedValue] with {
28-
def cpsApply(
25+
upstreamDsl: Dsl.Searching[Upstream, Domain, UpstreamValue],
26+
nestedDsl: Dsl.Searching[Mapped, Domain, MappedValue]
27+
): Dsl.Composed[FlatMap[Upstream, Mapped], Domain, MappedValue] = Dsl.Composed {
28+
(
2929
keyword: FlatMap[Upstream, Mapped],
3030
handler: MappedValue => Domain
31-
): Domain = {
31+
) =>
3232
val FlatMap(upstream, flatMapper) = keyword
33-
upstreamDsl.cpsApply(
33+
upstreamDsl(
3434
upstream,
3535
{ upstreamValue =>
3636
// The typer might erase the type of of parameter of the function
3737
// when the parameter is a reference to a local value, therefore,
3838
// we are unable to call `flatMapper` without a cast.
39-
nestedDsl.cpsApply(flatMapper.asInstanceOf[UpstreamValue => Mapped](upstreamValue), handler)
39+
nestedDsl(flatMapper.asInstanceOf[UpstreamValue => Mapped](upstreamValue), handler)
4040
}
4141
)
42-
}
42+
4343
}
4444
}

keywords-Get/src/main/scala/com/thoughtworks/dsl/keywords/Get.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ object Get {
1414
given [S]: IsKeyword[Get[S], S] with {}
1515
def apply[S]: Get[S] = Dsl.Keyword.Opaque.Of(())
1616

17-
implicit def getDsl[S0, S <: S0, A]: Dsl[Get[S0], S => A, S0] = new Dsl[Get[S0], S => A, S0] {
18-
def cpsApply(keyword: Get[S0], handler: S0 => S => A): S => A = { b =>
19-
handler(b)(b)
17+
given [S0, S <: S0, A]: Dsl.Atomic[Get[S0], S => A, S0] =
18+
Dsl.Atomic[Get[S0], S => A, S0] {
19+
(keyword: Get[S0], handler: S0 => S => A) => b =>
20+
handler(b)(b)
2021
}
21-
}
2222

2323
}

keywords-If/src/main/scala/com/thoughtworks/dsl/keywords/If.scala

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,37 @@ import Dsl.IsKeyword
44
import Dsl.cpsApply
55

66
final case class If[+ConditionKeyword, +ThenKeyword, +ElseKeyword](
7-
cond: ConditionKeyword,
8-
thenp: ThenKeyword,
9-
elsep: ElseKeyword) extends Dsl.Keyword.Trait
7+
cond: ConditionKeyword,
8+
thenp: ThenKeyword,
9+
elsep: ElseKeyword
10+
) extends Dsl.Keyword.Trait
1011

1112
object If {
1213
given [ConditionKeyword, ThenKeyword, ThenValue, ElseKeyword, ElseValue](using
13-
IsKeyword[ThenKeyword, ThenValue],
14-
IsKeyword[ElseKeyword, ElseValue],
15-
): IsKeyword[If[ConditionKeyword, ThenKeyword, ElseKeyword], ThenValue | ElseValue] with {}
16-
given[ConditionKeyword, ThenKeyword, ElseKeyword, Domain, Value](
17-
using
18-
Dsl.PolyCont[ConditionKeyword, Domain, Boolean],
19-
Dsl.PolyCont[ThenKeyword, Domain, Value],
20-
Dsl.PolyCont[ElseKeyword, Domain, Value],
21-
): Dsl.PolyCont[If[ConditionKeyword, ThenKeyword, ElseKeyword], Domain, Value] with {
22-
def cpsApply(keyword: If[ConditionKeyword, ThenKeyword, ElseKeyword], handler: Value => Domain): Domain = {
23-
keyword.cond.cpsApply{
14+
IsKeyword[ThenKeyword, ThenValue],
15+
IsKeyword[ElseKeyword, ElseValue]
16+
): IsKeyword[
17+
If[ConditionKeyword, ThenKeyword, ElseKeyword],
18+
ThenValue | ElseValue
19+
] with {}
20+
given [ConditionKeyword, ThenKeyword, ElseKeyword, Domain, Value](using
21+
Dsl.Searching[ConditionKeyword, Domain, Boolean],
22+
Dsl.Searching[ThenKeyword, Domain, Value],
23+
Dsl.Searching[ElseKeyword, Domain, Value]
24+
): Dsl.Composed[If[
25+
ConditionKeyword,
26+
ThenKeyword,
27+
ElseKeyword
28+
], Domain, Value] = Dsl.Composed {
29+
(
30+
keyword: If[ConditionKeyword, ThenKeyword, ElseKeyword],
31+
handler: Value => Domain
32+
) =>
33+
keyword.cond.cpsApply {
2434
case true =>
2535
keyword.thenp.cpsApply(handler)
2636
case false =>
2737
keyword.elsep.cpsApply(handler)
2838
}
29-
}
3039
}
31-
}
40+
}

0 commit comments

Comments
 (0)