Let's talk about types, pt 1
Now finally, we come to one of the topics surrounding Scala that makes it so badass, which is the type system it uses. We already discussed briefly that Scala is strongly typed – everything in Scala has a type. That type is also known when we compile our program, which means that Scala is also statically typed. Because Scala knows the types of everything at compile time, it can catch all kinds of errors that other languages can’t! That’s pretty cool.
Type-safety
Well if Scala can find common type errors for us, what exactly do those errors look like? Well, some languages (and we won’t point fingers) will let you do silly things like make a variable an Int and then later make it a String. I guess that’s fine if you’re a really good and smart programmer who can keep track of what methods the variable you made has based on the type of object it is right now, but I’m a bad and dumb programmer, so when I go to call + on my (formerly) Int to add another number to it, I will be sorely disappointed with the results!
> var a = 5 undefined > a 5 > a + 12 17 > a = "what is this i don't even" 'what is this i don\'t even' > a + 12 'what is this i don\'t even12'
Well that is not what I wanted at all! Compiler, why would you do this to me?! What have I done to upset you?
Scala, on the other hand, allows no such nonsense[1]. In Scala, pretty much everything is type-safe, meaning it won’t let something attempt to be a thing that it isn’t! If I declare a variable of 5 in Scala, it will have the Int type. Now, despite declaring that as a var so its value could actually change to something other than 5, the type of that variable will always be Int! If I try to change that variable to anything other than a new Int, Scala will refuse to compile it with great vengance.
scala> var a = 5 a: Int = 5 scala> a = "i think it's going to break" <console>:8: error: type mismatch; found : String("i think it\'s going to break") required: Int a = "i think it's going to break" ^
That’s Scala’s way of saying “You sir, have attempted to use a String where I require an Int, and are you sure you know what you’re doing?”
Type Inference
When I tell Scala “Hey buddy, just to let you know, var a = 5”, it knows I want an Int. Well actually, it infers that I want an Int, so that had better be what I wanted. You see, Scala has some smart guys who decided that a constant number typed into the code that wasn’t followed by a . and some more numbers and isn’t particularly large is probably an Int. It does this because as I mentioned before, everything in Scala must have a type, and if Scala is going to support saying var a = and then something after that, it must have some mechanism for supporting such wishy-washy declarations. For the most part with simple decisions like this, Scala does a really good job!
scala> var b = 5.0 b: Double = 5.0 scala> var c = "5" c: String = 5 scala> var d = '5' d: Char = 5 scala> var e = true e: Boolean = true scala> var f = null f: Null = null scala> var g = List('x, 'y, 'z) g: List[Symbol] = List('x, 'y, 'z)
However, as we’ve seen before, if we make a little typo, this could turn out to be precisely not what we wanted:
scala> var h = List('x, 'y', 'z) h: List[Any] = List('x, y, 'z)
You see, Any is a pretty good parent type to assign to a List containing both Symbol and Char elements, since Any is at the root of the Scala class hierarchy. Scala inferred that for us, because we gave it (perhaps errantly) two different kinds of objects without telling it specifically what kind of objects we wanted in our collection. So, it looked far and wide through the class hierarchy for a class that could be both Char and Symbol and ended up with Any. While it is true that we could be using objects of type Char as instances of Any, if we expected to have Chars and attempted to do something that Chars can do and Anys cannot, we would then get an error.
scala> h.head < h(1) <console>:9: error: value < is not a member of Any h.head < h(1) ^
This is one of the reasons that many Scala developers who work deeply within its type system lament how it works. It seems really cool and handy at first, but if you rely on type inference, it’s easy to get yourself into a sticky situation.
In the second half of this chunk, we'll take a look at how to declare the types of your objects, and see what type parameters look like for generic types.
That’s actually a lie, Scala will allow all kinds of nonsense if you ask it very nicely by writing a lot of code. ↩











