-
-
Save milessabin/4973733 to your computer and use it in GitHub Desktop.
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_05). | |
Type in expressions to have them evaluated. | |
Type :help for more information. | |
scala> def foo = { println("foo"); "foo" } | |
foo: String | |
scala> def bar = { println("bar"); "bar" } | |
bar: String | |
scala> def baz = { println("baz"); "baz" } | |
baz: String | |
scala> lazy val List(a, b, c) = List(foo, bar, baz) | |
a: String = <lazy> | |
b: String = <lazy> | |
c: String = <lazy> | |
scala> a | |
foo | |
bar | |
baz | |
res0: String = foo | |
scala> b | |
res1: String = bar | |
scala> c | |
res2: String = baz |
I think it's doing what I would expect: Scala's Lists are strict, not lazy, so if you force the list you force the contents. You can get even more Haskellish behaviour if you use wrap the List elements in scalaz's Need. I'll post another gist with an example of that.
The reason all three values are forced isn't because lists are strict, it's because tuples are. When you declare:
lazy val List(a, b, c) = List(foo, bar, baz)
The compiler translates it to something like:
lazy val anon$ = List(foo, bar, baz) match { case List(a, b, c) => (a, b, c) }
lazy val a = anon$._1
lazy val b = anon$._2
lazy val c = anon$._3
When a
is forced, it forces anon$
which is a tuple (constructed on the right hand side of the synthetic case clause). Tuple fields are strict. This sort of feels like a language spec bug to me... It seems like you want the compiler to synthesize some sort of LazyTuple
in cases like this instead.
By the way, just to prove the issue isn't list strictness:
scala> lazy val Stream(a,b,c) = Stream.iterate(0, 3) { x => println("oh noes"); x + 1 }
a: Int = <lazy>
b: Int = <lazy>
c: Int = <lazy>
scala> a
oh noes
oh noes
res0: Int = 0
Not what I would have expected!
a
,b
, andc
are tied together in an unfortunate way. Why must the first call toa
essentially makeb
andc
no longer lazy? The entireList(a, b, c)
is lazy, so by calling one value from it, the entire List (i.e. all its contents) are called?