Cannot invoke vararg methods in scala - scala

I'm creating a combinator parser in scala. The parse tree consists of Actions I need to visit when evaluating the parsed expression. One of these actions (the Function) will call a method on another object by reflection, but this fails when that is a vararg-method.
This is the code demonstrating the problem:
import scala.reflect.runtime.universe._
class M {
def e: Double = { Math.E }
def add(x: Double, y: Double): Double = { x + y }
def sin(x: Double): Double = { Math.sin(x * Math.PI / 180) }
def max(args: Double*): Double = { args.max }
}
sealed trait Action { def visit: Double }
case class Number(value: Double) extends Action { def visit: Double = value }
case class Function(Name: String, Args: Action*) extends Action {
def visit: Double = {
typeOf[M].member(Name: TermName) match {
case NoSymbol => throw new Error(s"Unknown function '$Name'")
case func: Symbol => runtimeMirror(getClass.getClassLoader).reflect(new M).reflectMethod(func.asMethod)(
(for { arg <- Args } yield arg.visit).toList: _*).asInstanceOf[Double]
}
}
}
object Parser {
def main(args: Array[String]) {
// Prints 2.718281828459045
println(Function("e").visit)
// Prints 7.0
println(Function("add", Number(3), Number(4)).visit)
// Prints 1.2246467991473532E-16
println(Function("sin", Number(180)).visit)
// Throws IllegalArgumentException: wrong number of arguments
println(Function("max", Number(1), Number(2.5), Number(50), Number(-3)).visit)
}
}
Anyone an idea how to fix this?

This is just a copy&paste solution, but I am sure you get the idea:
case class VarArgsFunction(Name: String, Args: Action*) extends Action {
def visit: Double = {
typeOf[M].member(Name: TermName) match {
case NoSymbol => throw new Error(s"Unknown function '$Name'")
case func: Symbol => {
runtimeMirror(getClass.getClassLoader).reflect(new M).reflectMethod(func.asMethod)(
(for { arg <- Args } yield arg.visit).toList).asInstanceOf[Double]
}
}
}
}
object Parser {
def main(args: Array[String]) {
// Prints 2.718281828459045
println(Function("e").visit)
// Prints 7.0
println(Function("add", Number(3), Number(4)).visit)
// Prints 1.2246467991473532E-16
println(Function("sin", Number(180)).visit)
// Throws IllegalArgumentException: wrong number of arguments
println(VarArgsFunction("max", Number(1), Number(2.5), Number(50), Number(-3)).visit)
}
}

Related

Packrat Parser in Scala hangs indefinitely even though there are no elements left in input

I've a custom packrat parser written to handle some tokens. However when running the parser it hangs indefinitely even though all tokens were matched successfully by the parser. However changing the return type of one matcher to Parser from PackratParser fixes the issue. Not sure what is causing this infinite loop.
Code:
import scala.util.parsing.combinator.{PackratParsers, Parsers}
import scala.util.parsing.input.{NoPosition, Position, Positional, Reader}
sealed trait MyToken extends Positional
case class STMT_START(str: String) extends MyToken
case class STMT_END(str: String) extends MyToken
case class Start(str: String) extends MyToken
case class End(str: String) extends MyToken
case class Statement(tokens: Seq[Start], endTokens: Seq[End]) extends MyToken
case class AllStatements(stmts: Seq[Statement]) extends MyToken
class MyParser extends Parsers with PackratParsers {
override type Elem = MyToken
class TokenReader(tokens: Seq[MyToken]) extends Reader[MyToken] {
override def first: MyToken = tokens.head
override def atEnd: Boolean = tokens.isEmpty
override def pos: Position =
tokens.headOption.map(_.pos).getOrElse(NoPosition)
override def rest: Reader[MyToken] = new TokenReader(tokens.tail)
}
def block: PackratParser[Statement] = {
positioned {
statementStart ~ statementEnd ^^ {
case STMT_START(str) ~ STMT_END(endStr) ⇒
Statement(
Start(str) :: Nil,
End(endStr) :: Nil
)
}
}
}
def myexpressions: PackratParser[AllStatements] = {
rep(block) ^^ { exprs ⇒
println(s"matched expressions - expr $exprs ")
AllStatements(exprs)
}
}
def statementStart: PackratParser[STMT_START] =
positioned {
accept(
"statementStart",
{
case jj # STMT_START(_) =>
println(s"PARSE: statementStart $jj")
jj
}
)
}
def statementEnd: PackratParser[STMT_END] =
positioned {
accept(
"statementEnd",
{
case jj # STMT_END(_) =>
println(s"PARSE: statementEnd $jj")
jj
}
)
}
def parse[T](tokens: List[MyToken], func: Input ⇒ ParseResult[T]): Unit = {
val reader = new PackratReader(new TokenReader(tokens))
func(reader) match {
case NoSuccess(msg, _) ⇒
println(s"Failed $msg")
case Success(result, next) ⇒
if (next.atEnd) println(s"result of parsing - $result")
else println("end of input expected")
}
}
}
object ParserTest {
def main(args: Array[String]): Unit = {
val test = new MyParser
val tokens = List(
STMT_START(" started"),
STMT_END("bla"),
STMT_START(" completed"),
STMT_END("bla")
)
test.parse(tokens, test.myexpressions)
}
}
Output:
PARSE: statementStart STMT_START( started)
PARSE: statementEnd STMT_END(bla)
PARSE: statementStart STMT_START( completed)
PARSE: statementEnd STMT_END(bla)
After this the program completely hangs, even though it prints that all 4 tokens were matched by the parser blocks.
Now in the same program if def block: PackratParser[Statement] is modified to def block: Parser[Statement] then the program runs fine and exists successfully.
Output:
PARSE: statementStart STMT_START( started)
PARSE: statementEnd STMT_END(bla)
PARSE: statementStart STMT_START( completed)
PARSE: statementEnd STMT_END(bla)
matched expressions - expr List(Statement(List(Start( started)),List(End(bla))), Statement(List(Start( completed)),List(End(bla))))
result of parsing - AllStatements(List(Statement(List(Start( started)),List(End(bla))), Statement(List(Start( completed)),List(End(bla)))))
Any idea what is causing this hang?

Extract Scala function name and params implicitly

I have the following code:
def disableRules(someId: String) = Action.async { implicit req =>
Metrics.measureTime("disableRules") {
someFutureOpr(someId).map(_ => Ok)
.recover {
case e: Exception => handlerError(s"Failure occurred on disableRules request ${e.getMessage}", "disableRules")
}
}
}
def activeRules(someId: String) = Action.async { implicit req =>
Metrics.measureTime("activeRules") {
someFutureOpr2(someId).map(_ => Ok)
.recover {
case e: Exception => handlerError(s"Failure occurred on activeRules request ${e.getMessage}", "activeRules")
}
}
}
...
As you can see, I have mesureTime and handleError functions that I pass to them the name of the function as String, is there way to make it implicitly, I mean its will take the function Name, if not - there way to extract the function Name and print it, also regarding params.
You can solve this with a macro (and no runtime reflection):
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
class CaptureImpl(val c: blackbox.Context) {
import c.universe._
def describe[T: c.WeakTypeTag](
expr: c.Expr[T]
): c.Expr[String] = c.Expr[String](q"(${expr.tree.toString()})")
}
object CaptureMethod {
def apply[T](expr: T): String = macro CaptureImpl.describe[T]
}
Example:
object Test {
def foo(): String = "hello"
def bar(a: Int): Int = a
def baz(s: String): String = s
def main(args: Array[String]): Unit = {
println(CaptureMethod(foo()))
println(CaptureMethod(bar(1)))
println(CaptureMethod(baz("yes")))
}
}
Yields:
Test.this.foo()
Test.this.bar(1)
Test.this.baz("yes")
Calculate it inside Metrics:
object Metrics {
def currentMethodName() : String = Thread.currentThread.getStackTrace()(3).getMethodName
def measureTime(): Unit = {
println(currentMethodName)
}
}
Then for example:
def a1() = {
Metrics.measureTime()
}
def a2() = {
Metrics.measureTime()
}
will output:
a1
a2
Is this a safe operation?
If we had:
def currentMethodName() : String = Thread.currentThread.getStackTrace.toList.mkString("\n")
we get:
java.lang.Thread.getStackTrace(Thread.java:1559)
HelloWorld1$Metrics$.currentMethodName(HelloWorld1.scala:69)
HelloWorld1$Metrics$.measureTime(HelloWorld1.scala:72)
HelloWorld1$.a1(HelloWorld1.scala:77)
HelloWorld1$.main(HelloWorld1.scala:103)
HelloWorld1.main(HelloWorld1.scala)
So we see that:
In index 0 we get getStackTrace.
In index 1 we have currentMethodName.
In index 2 we have measureTime.
Since measureTime is not the first method of the stack trace, fir sure we have another element in the stack trace. Therefore in your case yes, it is safe.

Within a function passed to a scala macro, I cannot reference a variable in scope

Cannot compile even if a function that handles function arguments is passed to macro.
A sample is shown below.
trait Generated[Z] {
def deserialize[A](t: A): Z
}
def from[A, Z](apl: A => Z): Generated[Z] = macro GeneratorMacro.from[A, Z]
class GeneratorMacro(val c: blackbox.Context) {
import c.universe._
def from[A: c.WeakTypeTag, Z: c.WeakTypeTag](apl: c.Expr[A => Z]): c.Expr[Generated[Z]] = {
reify {
new Generated[Z] {
def deserialize[A](t: A): Z = {
apl.splice.apply(t)
}
}
}
}
}
object Generation {
def apply(input: String): Generated[Int] = {
Generator.from[Option[String], Int] {
case Some(i) => input.toInt + i.toInt // compilation failed
case None => 0
}
}
}
An error occurs at this time.
Error: scalac: Error while emitting Generation.scala
value input
Isn't the class recompiled with the macro expanded?
If recompiled with inline expansion, no compilation error should occur.
object Generation {
def apply(input: String): Generated[Int] = {
new Generated[Int] {
def deserialize(t: String): Int = {
{
case Some(i) => input.toInt + i.toInt // input should be visible
case None => 0
}.apply(t)
}
}
}
}
What is going on and how to avoid it.
This seems to be impossible, AFAICS. The compiler creates an anonymous class for your code, but it will not capture the lexical context of the macro call inside it.
The code looks a bit like this after the lambdalift phase:
def apply(input: String): Generated[Int] = ({
new <$anon: Generated>()
}: Generated);
...
final class $anon extends Object with Generated {
def deserialize(t: Option): Int = {
... // <- your code is here !!
};
}
Of course, the code has no access to the input variable at this place.
This might be a bug in the Scala compiler...
The first error I have is
Warning:scalac: {
final class $anon extends App.this.Generated[Int] {
def <init>() = {
super.<init>();
()
};
def deserialize(t: Option[String]): Int = ((x0$1: Option[String]) => x0$1 match {
case (value: String)Some[String]((i # _)) => scala.Predef.augmentString(input).toInt.+(scala.Predef.augmentString(i).toInt)
case scala.None => 0
}).apply(t)
};
new $anon()
}
Error:(6, 43) object creation impossible. Missing implementation for:
def deserialize[A](t: A): Int // inherited from trait Generated
Generator.from[Option[String], Int] {
Obviously this is because you define
reify {
new Generated[Z] {
def deserialize(t: A): Z = {
...
instead of def deserialize[A](t: A): Z (#OlegPyzhcov pointed this out in the comments).
Regarding your error Error while emitting ... the thing is that
{
case Some(i: String) => input.toInt + i.toInt
case None => 0
}
has type not ... => ... i.e. Function1[..., ...] but actually PartialFunction[..., ...].
Try either
object Generator {
def from[Z](apl: PartialFunction[Any, Z]): Generated[Z] = macro GeneratorMacro.from[Z]
}
class GeneratorMacro(val c: blackbox.Context) {
import c.universe._
def from[Z: c.WeakTypeTag](apl: c.Expr[Any => Z]): c.Expr[Generated[Z]] = {
reify {
new Generated[Z] {
def deserialize[A](t: A): Z = {
apl.splice.apply(t)
}
}
}
}
}
Generator.from[Int]({
case Some(i: String) => input.toInt + i.toInt
case None => 0
})
or
object Generator {
def from[Z](apl: Any => Z): Generated[Z] = macro GeneratorMacro.from[Z]
}
class GeneratorMacro(val c: blackbox.Context) {
import c.universe._
def from[Z: c.WeakTypeTag](apl: c.Expr[Any => Z]): c.Expr[Generated[Z]] = {
reify {
new Generated[Z] {
def deserialize[A](t: A): Z = {
apl.splice.apply(t)
}
}
}
}
}
Generator.from[Int](new (Any => Int) {
override def apply(x: Any): Int = x match {
case Some(i: String) => input.toInt + i.toInt
case None => 0
}
})

How to parametrize class and implement method depends on type in Scala

This is what I tried. Depends on what does user put into the function I want to add String or Double to new Chunk.
package org.apache.spark.h2o.utils
import water.fvec.{NewChunk, Frame, Chunk}
import water._
import water.parser.ValueString
class ReplaceNa[T >: Any](a: T) extends MRTask{
override def map(c: Chunk, nc: NewChunk): Unit = {
for (row <- 0 until c.len()) {
a match{
case s: ValueString if(c.isNA(row)) => nc.addStr(s)
case d: Double if(c.isNA(row)) => nc.addNum(d)
}
}
}
}
But I got error
error: value outputFrame is not a member of Nothing
pred.add(new ReplaceNa(3).doAll(1, pred.vec(4)).outputFrame(Array("s"), null))
Thanks for your help!
I have several comments:
check for NA outside the switch branch
you are missing non-NA case hence you are generating vector which is shorter than input vector (i expect you would like to generate the same length vector)
Regarding generics, you need to provide type specialization. For example, something like the following snippet:
class ReplaceNA[T](val value: T)(implicit add: TAdd[T]) extends MRTask[ReplaceNA[T]] {
override def map(c: Chunk, nc: NewChunk): Unit = {
for (row <- 0 until c.len()) {
// Replace NAs by given value
if (c.isNA(row)) {
add.addValue(nc, value)
} else {
// Do something with default value
nc.addNA()
}
}
}
}
trait TAdd[T] extends Serializable {
def addValue(nc: NewChunk, value: T)
}
object TAdd extends Serializable {
implicit val addDouble = new TAdd[Double] { def addValue(nc: NewChunk, value: Double) = nc.addNum(value) }
implicit val addFloat = new TAdd[Float] { def addValue(nc: NewChunk, value: Float) = nc.addNum(value) }
implicit val addValueString = new TAdd[ValueString] { def addValue(nc: NewChunk, value: ValueString) = nc.addStr(value) }
}

scala - constrain generic type to specific types

from time to time, i deal with java that has stuff like the following in it:
def printDbl(d:Double) { println("dbl: " + d) }
def printInt(i:Int) { println("int: " + i) }
naturally, i'd like to wrap this in some scala, which ends up looking like this:
def print[T:Manifest] (t:T) {
if (manifest[T] <:< manifest[Int]) { printInt(t.asInstanceOf[Int]) ; return }
if (manifest[T] <:< manifest[Double]) { printDbl(t.asInstanceOf[Double]) ; return }
throw new UnsupportedOperationException("not implemented: " + manifest[T])
}
but when i run the following, i get a runtime exception:
print(1)
print(2.0)
print("hello")
i seem to recall there being a way to catch this at compile time, but i can't seem to google it up. perhaps some clever implied conversions?
Why don't you just take advantage of method overloading and write your Scala wrapper like this?:
object Printer {
def print(d: Double) { printDbl(d) }
def print(i: Int) { printInt(i) }
}
This is very simple and provides the desired behavior:
import Printer._
print(1.) // dbl: 1.0
print(1) // int: 1
print("hello") // compile-time type error
scala> object SpecType {
| trait SpecType[T] {
| def is(s: String): Boolean
| }
| implicit object DoubleType extends SpecType[Double] {
| def is(s: String) = s == "Double"
| }
| implicit object IntType extends SpecType[Int] {
| def is(s: String) = s == "Int"
| }
| }
defined module SpecType
scala> import SpecType._
import SpecType._
scala> def print[T: SpecType](x: T) {
| if(implicitly[SpecType[T]].is("Int")) println("Int")
| if(implicitly[SpecType[T]].is("Double")) println("Double")
| }
print: [T](x: T)(implicit evidence$1: SpecType.SpecType[T])Unit
scala> print(1)
Int
scala> print(1.0)
Double
scala> print("")
<console>:21: error: could not find implicit value for evidence parameter of typ
e SpecType.SpecType[String]
print("")
this is the best i've come up with
class CanPrint[T] (t:T) { def getT = t}
implicit def canPrint(i:Int) = new CanPrint[Int](i)
implicit def canPrint(d:Double) = new CanPrint[Double](d)
def print[T:Manifest] (t:CanPrint[T]) {
if (manifest[T] <:< manifest[Int]) { printInt(t.getT.asInstanceOf[Int]) ; return }
if (manifest[T] <:< manifest[Double]) { printDbl(t.getT.asInstanceOf[Double]) ; return }
throw new UnsupportedOperationException("not implemented: " + manifest[T])
}
the following does not compile
print(1)
print(1.0)
print("hello")
and the following does what i expect
print(1)
print(1.0)
however, this is bad code because i have to import the implicit defs for it to work, and as a consumer of this code all i see is the method signature saying that i have to pass in a CanPrint object, which i can instantiate.
print(new CanPrint("hello")) // pwned
can i make the constructor private and only accessible to the implicit methods or some such?
def printDbl(d:Double) { println("dbl: " + d) }
def printInt(i:Int) { println("int: " + i) }
trait Printer[T] { def print(t:T) }
class PD extends Printer[Double] { def print(d:Double) = printDbl(d) }
class PI extends Printer[Int] { def print(i:Int) = printInt(i) }
implicit val pd = new PD()
implicit val pi = new PI()
def print[T](t:T)(implicit printer:Printer[T]) = printer.print(t)
print(1) // 1
print(2.0) // 2.0
print("hello") // Error:(88, 7) could not find implicit value for parameter printer: A$A336.this.Printer[String]