Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New desugaring behavior in Scala 2.10.1

Tags:

Suppose I have this monadic class:

case class Foo[A](xs: List[A]) {   def map[B](f: A => B) = Foo(xs map f)   def flatMap[B](f: A => Foo[B]) = Foo(xs flatMap f.andThen(_.xs))   def withFilter(p: A => Boolean) = {     println("Filtering!")     Foo(xs filter p)   } } 

The following is from a 2.10.0 REPL session:

scala> for { (a, b) <- Foo(List(1 -> "x")) } yield a res0: Foo[Int] = Foo(List(1)) 

And here's the same thing in 2.10.1:

scala> for { (a, b) <- Foo(List(1 -> "x")) } yield a Filtering! res0: Foo[Int] = Foo(List(1)) 

This is completely unexpected (to me), and leads to particularly confusing errors in cases where filtering requires additional constraints (such as Scalaz's \/ or EitherT).

I wasn't able to find any discussion of this change in the 2.10.1 release notes. Can someone point out where and why this new desugaring behavior was introduced?

like image 291
Travis Brown Avatar asked Jul 02 '13 11:07

Travis Brown


1 Answers

The story is more complex than that, and it's in fact a 2.10.0 regression that was plugged there.

The "no-withFilter" behavior was introduced in c82ecab, and because of things like SI-6968, this was reverted partially #1893. Further adaptations followed (SI-6646, SI-7183)

The takeaway sentence you're looking for is :

The parser can't assume that a pattern (a, b) will match, as results of .isInstanceOf[Tuple2] can't be statically known until after the typer.

like image 80
Francois G Avatar answered Oct 23 '22 00:10

Francois G