Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-strict view of scanLeft

Tags:

scala

I encountered a problem. scanLeft works different with an Iterator, a Stream, and a view. I'm not sure where this difference comes from. Let's look at this example:

scala> (1 to 4).iterator.scanLeft(0)((a,b) => { println(b) ; a + b}).take(2).toList
1
2
res1: List[Int] = List(0, 1)

scala> (1 to 4).toStream.scanLeft(0)((a,b) => { println(b) ; a + b}).take(2).toList
1
res2: List[Int] = List(0, 1)

scala> (1 to 4).view.scanLeft(0)((a,b) => { println(b) ; a + b}).take(2).toList
1
2
3
4
res4: List[Int] = List(0, 1)

The strangest thing is with view. It's behaving like it was not lazy. However, when using .map, it's ok.

scala> (1 to 4).view.map{ b => println(b) ; b}.take(2).toList
1
2
res9: List[Int] = List(1, 2)

Can somebody tell me the reason? Thanks in advance

like image 410
MikeD Avatar asked Sep 08 '15 21:09

MikeD


1 Answers

It's a bug in views. There are many such bugs. See https://issues.scala-lang.org/browse/SI-4332 for details. (My comment of 04/Jan/2013 is me noticing the same thing you did about scanLeft.)

Because of their many quality issues, I never use views in my own code and I don't recommend them to others, either.

There is an effort underway to replace views with something better; see https://github.com/scala/slip/pull/17. In the meantime, I suggest treating them as deprecated, even though they have not been formally deprecated.

like image 131
Seth Tisue Avatar answered Oct 10 '22 22:10

Seth Tisue