Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TupledFunctions vs Tuple Function #84

Open
tzbob opened this issue Dec 16, 2014 · 0 comments
Open

TupledFunctions vs Tuple Function #84

tzbob opened this issue Dec 16, 2014 · 0 comments
Labels

Comments

@tzbob
Copy link

tzbob commented Dec 16, 2014

Imagine a scenario where you want to wrap a third-party higher-order polymorphic function like so:

  trait LambdaMap extends ListOps with TupledFunctions {
    def map[T: Manifest](l: Rep[List[T]], callback: Rep[T => T]): Rep[List[T]]
  }

  trait LambdaMapExp extends LambdaMap with ListOpsExp with TupledFunctionsExp {
    case class LambdaMap[T:Manifest](l: Exp[List[T]], callback: Exp[T => T]) extends Def[List[T]]
    def map[T: Manifest](l: Exp[List[T]], callback: Exp[T => T]): Exp[List[T]] =
      LambdaMap(l, callback)
  }

  trait GenLambdaMap extends ScalaGenListOps with ScalaGenTupledFunctions {
    val IR: LambdaMapExp
    import IR._

    override def emitNode(sym: Sym[Any], rhs: Def[Any]) = rhs match {
      case LambdaMap(l,callback) => emitValDef(sym, src"$l.map($callback)")
      case _ => super.emitNode(sym, rhs)
    }
  }

  trait LambdaMapUse extends LambdaMap {
    def test[T: Manifest](xs: Rep[List[T]]): Rep[List[T]] =
      map(xs, fun { x: Rep[T] => x })
  }

So generating our 'test' function where T == Double gives us the correct functionality:

class Test extends ((scala.collection.immutable.List[Double])=>(scala.collection.immutable.List[Double])) {
def apply(x0:scala.collection.immutable.List[Double]): scala.collection.immutable.List[Double] = {
val x2 = {x1: (Double) => 
x1: Double
}
val x3 = x0.map(x2)
x3
}
}

While generating our 'test' function where T == (Double, Double) gives us the wrong functionality:

class Test extends ((scala.collection.immutable.List[scala.Tuple2[Double, Double]])=>(scala.collection.immutable.List[scala.Tuple2[Double, Double]])) {
def apply(x0:scala.collection.immutable.List[scala.Tuple2[Double, Double]]): scala.collection.immutable.List[scala.Tuple2[Double, Double]] = {
val x3 = {(x1:Double,x2:Double) => 
((x1,x2)): scala.Tuple2[Double, Double]
}
val x4 = x0.map(x3)
x4
}
}

Due to the autoboxing and unboxing going on with tupled functions I'm not sure how this issue would be resolved? It seems that the 'standard library' of LMS avoids these problems by staging at a different scope e.g. Rep[A] => Rep[B] vs Rep[A => B] with more work being done in the expression layer and generation phase.

I'm not sure if this is a bug or just intended behaviour, so how should I go about this problem? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants