scalanlp / breeze

Breeze is/was a numerical processing library for Scala.
https://www.scalanlp.org
Apache License 2.0
3.45k stars 692 forks source link

Compilation fails with SBT when using DenseVector(index) inside for expression and using toSet #65

Open tburny opened 11 years ago

tburny commented 11 years ago

Today I ran across a bug during the "specialize" phase of the Scala compiler/sbt.

The following fails to compile (with an assertion error): def test() = { val row = DenseVector(1,2,3,4) for (j <- 0 until row.length if (row(j) > 3)) yield j }

whereas the following compiles

def test() = { val row = DenseVector(1,2,3,4) for (j <- 0 until row.length if (5 > 3)) yield j }

As you can see, the only difference is that row(j) has been replaced by a concrete value. This also works: def test() = { val row = DenseVector(1,2,3,4) for (j <- 0 until row.length if (row.valueAt(j) > 3)) yield j }

I'm using SBT 12.2 with Scala 2.10.1. I also tried with Scala 2.10.0 with no difference.

Stack trace: https://gist.github.com/tburny/5650247 Source: https://github.com/tburny/bayesian-personalized-ranking/blob/8312ce8fe623ab1480b911e93beed96da6b0e0b9/src/main/scala/de/burnynet/BPRModel.scala in methods usersWhichRatedItemPositive and positiveItemRatingsByUser

dlwh commented 11 years ago

Hrm, there's not much I can do about that. Can you file a bug against Scala? You can add the flag -no-specialize---with the understanding that it makes your code slower---in the meantime, though you have an ok workaround.

On Sat, May 25, 2013 at 11:40 AM, tburny notifications@github.com wrote:

Today I ran across a bug during the "specialize" phase of the Scala compiler/sbt.

The following fails to compile (with an assertion error): def test() = { val row = DenseVector(1,2,3,4) (for (j <- 0 until row.length if (row(j) > 3)) yield j).toSet }

whereas the following compiles

def test() = { val row = DenseVector(1,2,3,4) (for (j <- 0 until row.length if (5 > 3)) yield j).toSet }

As you can see, the only difference is that row(j) has been replaced by a concrete value. This also works: def test() = { val row = DenseVector(1,2,3,4) (for (j <- 0 until row.length if (row.valueAt(j) > 3)) yield j).toSet }

I'm using SBT 12.2 with Scala 2.10.1. I also tried with Scala 2.10.0 with no difference.

Stack trace: https://gist.github.com/tburny/5650247 Project where the problem occurred: https://github.com/tburny/bayesian-personalized-ranking

— Reply to this email directly or view it on GitHubhttps://github.com/scalanlp/breeze/issues/65 .

dlwh commented 11 years ago

(still a problem in 2.10.2)

This is ok:

scala> class DV[@specialized(Int) T](data: Array[T]) { @inline def apply(i: Int) = data(i); def length = data.length }
defined class DV

scala> val row = new DV[Int](Array(1,2,3,4))
row: DV[Int] = DV@6eb65209

scala> (for (j <- 0 until row.length if (row(j) > 3)) yield j).toSet
res3: scala.collection.immutable.Set[Int] = Set(3)
dlwh commented 11 years ago

(I'm getting variants of this bug in several places, I'm going to try to sort it out soon.)

dlwh commented 10 years ago

https://issues.scala-lang.org/browse/SI-8572