When Martin Odersky talks about scala as a scalable language choice, what he means is that the language itself is appropriate for:
- scripting stuff
- writing applications
- writing monster "enterprise" (for the want of a better word) applications
He is most certainly not referring to scalability from the perspective of performance!
The fact that he can claim that scala is as appropriate for quick'n'dirty scripting as it is for large-scale enterprise deployment is roughly as follows:
Scripting
Scala is great for scripting because its type inference and functional style make it both concise and great for slicing and dicing collections etc.
Applications
Scala is great for writing applications because it is a statically type checked language with some great features for working in both functional and imperative styles. Scala is compatible with Java and hence you can leverage an enormous ecosystem of libraries.
Enterprise Deployment
Scala compiles to bytecode and runs on the Java Virtual Machine, a stable system with great performance, when compared to (so-called) dynamically typed (i.e. untyped) languages. Again, the fact that it is statically typed means that refactoring is made much easier on large codebases.
Scala doesn't require an explicit return type on all functions, just recursive ones. The reason for that is that Scala's type inference algorithm is (something close to) a simple scan from beginning to end that is incapable of lookahead.
This means that a function like this:
def fortuneCookieJoke(message: String) = message + " in bed."
doesn't need a return type, since the Scala compiler can clearly see, without using logic variables or looking at anything other than the method's parameters, that the return type must be String
.
On the other hand, a function like this:
def mapInts(f: (Int) => Int, l: List[Int]) = l match {
case Nil => Nil
case x :: xs => f(x) :: mapInts(f, xs)
}
will cause a compile-time error, because the Scala compiler cannot see, without using either lookahead or logic variables, exactly what the type of mapInts
is. The most it could say, if it were smart enough, is that the return type is a supertype of List[Nothing]
, since Nil
is of that type. That doesn't give it anywhere near enough information to accurately determine the return type of mapInts
.
Please note that this is specific to Scala, and that there are other statically typed languages (most of the Miranda/Haskell/Clean family, most of the ML family, and a few scattered others) that use much more comprehensive and capable type inference algorithms than Scala uses. Also, be aware that this is not entirely Scala's fault; nominal subtyping and whole-module type inference are fundamentally at odds with each other, and the designers of Scala chose to favor the former over the latter for the sake of Java compatibility, while the "purer" statically typed functional languages were mostly designed with the opposite choice in mind.
Best Answer
Subtyping and inheritance are two different things!
Nothing
doesn't extend everything, it's a subtype, it only extendsAny
.The specification[§3.5.2] has a special case governing the subtyping-relationship of
Nothing
:Where
<:
basically means "is a subtype of".As for how this is done: We don't know, it's compiler magic and an implementation detail.
Quite often a language does things you as a programmer can't. As a counterpart to
Nothing
: Everything in Scala inherits fromAny
, everything exceptAny
. Why doesn'tAny
inherit from something? You can't do that. Why can Scala do that? Well, because Scala set the rules, not you.Nothing
being a subtype of everything is just an other instance of this.