Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I be modifying a Nil list?

Tags:

scala

You know that scene in Goodbye and Thanks For All The Fish where Arthur is so deliriously happy he stops a waiter and demands to know, "Why is this food so good?" I'm in that situation. Scala seems to be doing exactly what I'd want, but I don't understand how it's doing it. Consider the following:

scala> var v = Nil:List[String];
v: List[String] = List()

scala> v.length
res38: Int = 0

scala> v ::= "Hello"

scala> v.length
res39: Int = 1

scala> Nil.length
res40: Int = 0

Which is exactly what you'd hope for, but how is it happening?

Nil is an object that extends List[Nothing], which is a subtype of List[String], so assignment works fine, but it's an immutable list, isn't it? So I shouldn't be able to append to it. But I can append to it, or at least I can append to v, which I thought point to Nil. v is changed, but Nil isn't.

So, WTF? Does Scala have some clever copy-on-modify semantics I'm unaware of? Is Nil really a function that returns empty lists? More broadly, is there some way I could have made the REPL answer these questions?

like image 756
Michael Lorton Avatar asked Dec 18 '10 01:12

Michael Lorton


1 Answers

When Scala sees

v ::= "Hello"

it first checks if v knows the method ::=. In this case (type List), it doesn't, so, because the method consists only of symbols and ends with an = sign, it tries something else:

v = v.::("Hello")

which, incidentally, is written "Hello" :: v in infix notation. Now, since v knows the method ::, that works and returns a new List, which is then assigned to v as indicated.

By the way, it is prepending, not appending.

like image 72
Daniel C. Sobral Avatar answered Oct 24 '22 01:10

Daniel C. Sobral