Question

How can i implement that DSL construction at Scala

def objeects(f: => Int):Int {
 println(f)
 // ??? evaluate every function, that f contain in the block. 
}          

manytimes {
 1+1
 2+1
 3+1
}                                              

At result we need get one computation for every functions as we pass in block to that method.

9
Was it helpful?

Solution 2

After many hours of searching i found some really great components, that can help me solve my problem.

multifunc { 
            println(1)
            println(2) 
          }
// output
Expr[c.universe.Tree](func.tree)
scala.this.Predef.println(2) // <-- it my case its the second and last elem
class scala.reflect.internal.Trees$Apply // <-- we can apply it as usual
class scala.reflect.internal.Trees$Block
tree<<
class scala.reflect.internal.Trees$EmptyTree$
<empty>

Macro for that: import scala.language.experimental.macros import scala.reflect.macros._ def multifunc[A](func: => A) = macro _multifunc[A]

def _multifunc [A](c: BlackboxContext)(
func: c.Expr[A]
): c.Expr[Unit] = {
import c.universe._

val tree = func.tree match {
  case q"($i: $t) => $body" => q"""
      println($body)
      println($body.getClass)
      $body
    """
  case _ => q""
}


println(func.tree.children.last) // <-- accessor to AST children
println(func.tree.children.last.getClass)
println(func.tree.getClass)
println("tree<<")
println(tree.getClass)
println(tree)
c.Expr(tree)
}

OTHER TIPS

Your block is one function:

{
 1+1 // calculate 2 and throw away
 2+1 // calculate 3 and throw away
 3+1 // return 4
}

This is simply how Scala syntax works, and you can't change it. Indeed, if you could, what would you expect to happen in this case?

manytimes {
  val x = 1
  val y = 2
  x + y
}

Will

manytimes(1+1)(2+1)(3+1)

be good enough for your purposes?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top