1

Is it so that Scala collections can only be initialized/assigned the literal values of vals, vars and literals, and not the vals/vars themselves?

I.e. the list b below will be (4, 3), and there would be no way to alternatively reference a from a collection rather than host its value in the collection?

val a = 3
val b = List(4, a)

Should I assume the only way to "accomplish" such referencing is to switch from data to objects, as objects are mostly referenced by default? using objects may not be very computation and memory efficient, where performance matters.

And regarding the pure performance aspects, say a were some large collection and not just a number, would Scala duplicate its "contents" in memory when the above initialization of b took place?

Thanks!

1
  • vals and vars are references (immutable and mutable respectively) and you can add them to collections like you have added a. Can you please clarify the question? Commented Sep 7, 2014 at 10:08

2 Answers 2

2

When you invoke the constructor of List, its arguments are evaluated immediately (call-by-value), hence the object 3 will be stored in the List.

In general, everything in scala is an object (leaving aside JVM representation details), so what you are storing is an immutable reference to 3, which is immutable in turn.

Also, note that - due to referencial transparency (a is a constant reference to 3) - storing a reference to a or the object it references to doesn't make a difference, i.e. it's "transparent".

So, if you instead want an opaque reference to something you can change later on, you can always store a constant reference to a mutable object:

scala> class Foo(var foo: Int)
defined class Foo

scala> val x = new Foo(42)
x: Foo = Foo@3a654e77

scala> val a = List(x)
a: List[Foo] = List(Foo@3a654e77)

scala> a.head.foo
res25: Int = 42

scala> x.foo = 43
x.foo: Int = 43

scala> a.head.foo
res26: Int = 43

but boy that's evil!


As per the performance question, if a is a large immutable collection, referencial transparency allows for reusing the existing collection a when constructing b, without pessimistically copy it. Since a cannot mutate, there's no need for cloning at all.

You can easily test this in the REPL:

Let's create an immutable collection a

scala> val a = List(1, 2)
a: List[Int] = List(1, 2)

Let's use a for creating b

scala> val b = List(a, List(3, 4))
b: List[List[Int]] = List(List(1, 2), List(3, 4))

The first element of b is exactly the same a we put it

scala> b.head eq a
res18: Boolean = true

Note that eq compares reference equality, so the above is not just a copy of a. Further proof:

scala> List(1, 2) eq a
res19: Boolean = false
Sign up to request clarification or add additional context in comments.

1 Comment

happy to get your comment to the augmentation I added below. Otherwise thanks again...
0

thanks for the great answer @Gabriele Petronella. This couldn't format as a comment so I just add it here as an augmentation.

I think that further to the point of references, the following can also be quite useful, although eq is a bit harder to plug into here.

scala> val a = MutableList(1,2) 
a: scala.collection.mutable.MutableList[Int] = MutableList(1, 2) 

scala> val b = List(a, 3, 4) 
b: List[Any] = List(MutableList(1, 2), 3, 4) 

scala> a += 100
res20: a.type = MutableList(1, 2, 100) 

scala> b 
res21: List[Any] = List(MutableList(1, 2, 100), 3, 4) 

Not sure how to phrase the relationship to referential transparency - but it really relates to the original question

1 Comment

yep, your example is basically the same thing as my first one. Immutable lists can store immutable references to mutable objects (tricky phrasing, I know) and you can definitely mutate such mutable objects they're pointing to. The reference hasn't changed, but the referenced object has.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.