I have the following two questions:
TL;DR jump to last paragraph :)
While I completely agree with Tiago's answer, there are a few things that can be added. As you know, Scala is a functional and object-oriented language. The functional aspect of it dictates that side-effects should be eliminated, or at least minimized as much as possible.
Throwing an exception is a side-effect since it is not referentially transparent (ie, it depends on the context of where the exception is thrown, for example if the exception is thrown from inside a try block, it will be caught whereas if it is thrown outside of that try block, it will alter the flow of the program).
Here is an example taken from the book Functional Programming in Scala (P. Chiusano, R. Bjarnason)
def failingFn(i: Int): Int = {
val y: Int = throw new Exception("fail!")
try {
val x = 42 + 5
x + y
}
catch { case e: Exception => 43 }
}
In the above code, y is not referentially transparent since if you replace it by its value within the try block, the result of the function will be different.
Ok, enough with all the theory, the key takeaway from the above is that throwing an exception is a side-effect and this violates the functional programming paradigm.
To address this, the designers of Scala decided to instead return "a value" that indicates that an exception occurred, instead of throwing one. For that reason, classes like Try (and its direct subtypes Success and Failure) were introduced. Instead of throwing an exception, you simply modify the return type of your function, wrapping it in a Try. This forces the client to check for success or failure without all the side-effects that throwing exceptions bring. The introduction of the Try type basically replaces checked exceptions since the client is implicitly made aware of the possibility of an exception at compile-time through the use of a Try return type.