Last active
October 21, 2024 14:29
-
-
Save fwbrasil/6d8d7f443f7487524a6a8db2ed70eb1d to your computer and use it in GitHub Desktop.
Java macro DSL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* THIS IS JUST A DSL PROTOTYPE | |
* | |
* First tentative of a DSL for defining macro transformations in Java. | |
* There's a lot of noise because of the absence of pattern matching and tuples. | |
* This is a prototype of one of the if/else transformations in Monadless: | |
* | |
* case q"if($cond) $ifTrue else $ifFalse" => | |
* (ifTrue, ifFalse) match { | |
* case (Transform(ifTrue), Transform(ifFalse)) => | |
* Some(q"if($cond) $ifTrue else $ifFalse") | |
* case (Transform(ifTrue), ifFalse) => | |
* Some(q"if($cond) $ifTrue else ${Resolve.apply(tree.pos)}($ifFalse)") | |
* case (ifTrue, Transform(ifFalse)) => | |
* Some(q"if($cond) ${Resolve.apply(tree.pos)}($ifTrue) else $ifFalse") | |
* case (ifTrue, ifFalse) => | |
* None | |
* } | |
* | |
* https://github.com/monadless/monadless/blob/master/monadless-core/src/main/scala/io/monadless/impl/Transformer.scala#L31 | |
* | |
* `when` is similar to pattern matching quasiquotes in Scala. The lambda | |
* inputs are the variables and the body, the pattern. | |
* | |
* For instance, | |
* case q"if($pred) $a else $b" => | |
* becomes | |
* when((Tree<Boolean> pred, Tree<T> a, Tree<T> b) -> pred.splice() ? a.splice() : b.splice()) | |
* | |
* `splice` within a `tree` call indicates that the tree must be inserted | |
* at the specified position. | |
*/ | |
class AsyncMacro { | |
@Macro | |
public <T> Tree<Future<T>> async(Tree<T> t) { | |
return transform(t).orElse(tree(Future.apply(t.splice()))); | |
} | |
private <T> Optional<Tree<Future<T>>> transform(Tree<T> t) { | |
return when((Tree<Future<T>> f) -> await(f.splice())).then(f -> tree(f.splice())) | |
.when((Tree<Boolean> pred, Tree<T> a, Tree<T> b) -> pred.splice() ? a.splice() : b.splice()) | |
.thenMaybe((pred, a, b) -> | |
transform(a).flatMap(tA -> | |
transform(b).map(tB -> | |
tree(pred.splice() ? tA.splice() : tB.splice()) | |
) | |
) | |
) | |
.thenMaybe((pred, a, b) -> | |
transform(a).map(tA -> | |
tree(pred.splice() ? tA.splice() : Future.apply(b.splice())) | |
) | |
) | |
.thenMaybe((pred, a, b) -> | |
transform(b).map(tB -> | |
tree(pred.splice() ? Future.apply(a.splice()) : tB.splice()) | |
) | |
) | |
.apply(t); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Example { | |
Future<Integer> test(boolean b) { | |
return async(b ? await(callServiceA()) : await(callServiceB())); | |
} | |
private Future<Integer> callServiceA() { | |
return null; // remote call | |
} | |
private Future<Integer> callServiceB() { | |
return null; // remote call | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment