Reputation: 5449
Can anyone please share insight into the trait "Immutable" in scala? At first glance I thought this would be a nice control structure to limit a class I'm building, but oddly I noticed that primitive types do not extend this. Is there a reason for this? Is there a way to bind the syntax to Immutable or AnyVal?
class Test {
def test[T<:Immutable](x:T)={
println("passes "+x)
}
case class X(s:String) extends Immutable
test(X("hello")) //passes
// test("fail") - does not pass compiler
}
Upvotes: 1
Views: 248
Reputation: 30736
The only direct subtypes of Immutable
in the Scala core library are:
collection.immutable.Traversable
collection.parallel.immutable.ParIterable
Nothing else refers to Immutable
at all.
Immutable
hasn't been changed since it was added in 2009 in Martin Odersky's "massive new collections checkin". I'm searching through that commit, and it looks like Immutable
was never even used as a bound when it was first introduced either.
Honestly, I doubt there's much intent behind these traits anymore. Odersky probably planned to use Immutable
to bound the type arguments on immutable collections, and then thought better of it. But that's just my speculation.
Upvotes: 2
Reputation: 26486
So-called primitive types (Boolean, Byte, Char, Short, Int, Long, Float, Double) are intrinsically immutable. 5 is 5 is 5. You cannot do anything to 5 to turn it into anything that is not 5.
Otherwise, immutability is a property of how a value is stored. If stored in a var
, that var
may be replaced freely with a new value (of a compatible type). By extension, constructed types (class
es, trait
s and object
s) may be either immutable or mutable depending on whether they allow any of their internal state to be altered following construction.
Java's String
(also used as Scala's String
) is immutable.
However, none of this has anything to do with you example, since you did not demonstrate mutability. You simply showed what happens when one applies the +
method of one value to another value.
While it is certainly possible that one can implement a +
method that mutates its (apparent) left-hand operand, one rarely does that. If there's a need for that kind of mutation, one would conventionally define the +=
method instead.
+
is somewhat special in that it may be applied to any value (if the argument / right-hand operand) is a String
by virtue of an implicit conversion to a special class that defines +(s: String)
so that the string concatenation interpretation of +
may be applied. In other words, if you write e1 + "e2"
and the type of the expression e1
does not define +
, then Scala will convert e1
to String
and concatenate it with "e2"
.
Upvotes: 2