Skip to content

Instantly share code, notes, and snippets.

@kubukoz
Created May 15, 2021 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kubukoz/2ea318ad41e6fde3c001073720752085 to your computer and use it in GitHub Desktop.
Save kubukoz/2ea318ad41e6fde3c001073720752085 to your computer and use it in GitHub Desktop.
New DSL ideas for Scala 3
trait ConsoleDsl {
// callers will never know what this is, and that's a good thing
type A
def println(s: String): A
def readLn: A
def combine(a: A, b: A): A
}
object ConsoleDsl {
type Aux[T] = ConsoleDsl { type A = T }
def dsl(using a: ConsoleDsl): a.type = a
extension [A](a: A)(using ConsoleDsl.Aux[A]) def +(another: A) = summon[ConsoleDsl.Aux[A]].combine(a, another)
}
object Framework {
def execute(program: (dsl: ConsoleDsl) ?=> dsl.A): String = {
given ConsoleDsl with {
type A = Int
def println(s: String): Int = 0
def readLn: Int = 1
def combine(a: Int, b: Int): Int = a + b
}
"foo" * program
}
}
import ConsoleDsl._
@main def hello = println {
Framework.execute {
// here, you can use the DSL but you still don't know what A is
// you can only operate on its values with the operators from the DSL
dsl.println("a")
+ dsl.println("a")
+ dsl.println("a")
+ dsl.readLn
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment