0

From my understanding the ultimate class in Scala is Any class. However, I thought Scala built of the Java, so would not the ultimate class be Object? I have been checking the documentation and I could be wrong but it does not show that Object is the parent class of Any nor can I see anywhere the java.lang package being imported into Scala, which should be its backbone right?

2
  • 1
    What does the ultimate class even mean? It can be seen as the terminal object depending on how you look at the type system but still... And Scala is DEFINITELY NOT built on Java. I don't know where you got that from. It runs on the JVM so it is able to interop with Java code. Commented Jun 3, 2020 at 3:49
  • My misunderstanding, sorry about that, and thank you for your response. Commented Jun 3, 2020 at 4:51

2 Answers 2

3

You are confusing the Scala Programming Language with one of its Implementations.

A Programming Language is a set of mathematical rules and restrictions. Not more. It isn't "written in anything" (except maybe in English) and it isn't "built off anything" (except maybe the paper that the specification is written on).

An Implementation is a piece of software that either reads a program written in the Programming Language and executes that program in such a way that the exact things that the Programming Language Specification say should happen, do happen (in which case we call the Implementation an Interpreter), or it reads the program and outputs another program in another language in such a way that executing that output program with an interpreter for its language makes things happen in exactly the way that the Specification for the input language says.

Either way, it is the job of the person writing the Implementation to make sure that his Implementation does what the Specification says it should do.

So, even if I am writing an Implementation of Scala that is "built off Java" and written in Java, I still need to make sure that Any is the top type, because that's what the Scala Language Specification says. It is probably instructive to look at how, exactly, the Scala Language Specification phrases this [bold emphasis mine]:

Classes AnyRef and AnyVal are required to provide only the members declared in class Any, but implementations may add host-specific methods to these classes (for instance, an implementation may identify class AnyRef with its own root class for objects).

There are currently three actively-maintained Implementations of Scala, and one abandoned one.

The abandoned Implementation of Scala is Scala.NET, which was a compiler targeting the Common Language Infrastructure. It was abandoned due to lack of interest and funding. (Basically, all the users that probably would have used Scala.NET were already using F#.)

The currently maintained Implementations of Scala are:

  • Scala-native: a compiled Implementation targeting unixoid Operating Systems and Windows.
  • Scala.js: a compiled Implementation targeting the ECMAScript and Web platform.
  • Scala (a rather unfortunately confusing name, because it is the same as the language): a compiled Implementation targeting the Java platform. And by "Java platform", I mean the Java Virtual Machine and the Java Runtime Environment but not the Java Programming Language.

All three Implementations are written 100% in Scala. Actually, they are not three fully independent implementations, they use the same compiler frontend with only different backends, and they use the same parts of the Scala Standard Library that are written in Scala, and only re-implement the parts written in other languages.

So, what is true is that the Java Implementation of Scala does indeed do something with java.lang.Object. However, java.lang.Object is not the superclass of scala.Any. In fact, it can't be because scala.Any is the root superclass of both reference types and value types, whereas java.lang.Object is only the root superclass of all reference types. Therefore, java.lang.Object is actually equivalent to scala.AnyRef and not to scala.Any. However, java.lang.Object is not the superclass of scala.AnyRef either, but rather, both are the same class.

Also, java.lang._ is automatically imported just like scala._ is. But this does not apply to the Scala Programming Language, it only applies to the Java Implementation of the Scala Programming Language, whose name is unfortunately also Scala.

So, only for one of the three Implementations, there is some truth to the statement that java.lang.Object is the root class, but it is not a superclass of scala.Any, rather it is the same class as scala.AnyRef.

But again, this is only true for the Java Implementation of Scala. For example, in Scala.NET, the root superclass would be identified with System.Object, not java.lang.Object, and it would be equivalent to scala.Any, not scala.AnyRef because the CLI has a unified type system like Scala where reference types and value types are unified in the same type system. And I haven't checked Scala.js, but I would assume that it would identify Object with scala.AnyRef.

Note, however, that none of this is because the Implementation is "built off" something. The reason for doing this, for trying to merge the Scala and Java / CLI / ECMAScript class hierarchy, is for interoperability, it is for making it easy to call Scala code from every other language on the Java / CLI / ECMAScript platform, and vice versa, call code written in other languages from Scala. If you didn't care about that, then there would be no need to jump through these hoops.

Sign up to request clarification or add additional context in comments.

5 Comments

Three questions I have: I am assuming the REPL also ends up compiling the code to JVM and then the java byte code is broken down to machine code just like Scala-Native? Scala-Native is the implementation most users on windows would be using right? In Java does not the JVM compile or interpret code depending, is not the same applied for Scala?
The REPL uses the Scala Compiler Toolbox to compile individual snippets and execute them. Whether or not it compiles to JVM depends on which Scala Implementation you use: Scala-JVM will compile to JVM, Scala.js will compile to ECMAScript, Scala-native will compile to native code. How the JVM executes the code depends on which JVM Implementation you are using. Some JVMs interpret, some compile, some interpret first and then compile the most often used parts of code. JVM byte code is just a language, a set of mathematical rules and restrictions. It could be implemented many different ways.
I don't think Scala-native is popular on Windows. I don't think Scala-native is popular at all. It is still under development, and is lagging behind Scala.js and Scala-JVM in language version. (The current version of the Scala Language Specification implemented by Scala-JVM is 2.13, with 3 already well underway. The current version of the Scala Language Specification implemented by Scala-native is 2.11.)
"In Java does not the JVM compile or interpret code depending, is not the same applied for Scala?" – Java is just a language, a set of mathematical rules and restrictions. It could be implemented many different ways. There is nothing in the Java Language Specification that says anything about a JVM. It would be perfectly legal to compile Java to native code, for example, without any JVM, and such implementations do (or at least did) exist. And even if you compile Java to the JVM, then there is still nothing in the Java Virtual Machine Specification that says anything about compilation or …
… interpretation. Any implementor is free to implement the JVM however they want. There are JVMs that interpret, there are JVMs that statically compile ahead-of-time, there are JVMs that dynamically compile just-in-time, there are JVMs that interpret, collect statistics, and then compile only the parts of code that statistically get executed the most often.
1

java.lang.Object is not the parent of scala.Any. Consider the following relationships

implicitly[Any <:< java.lang.Object]     // error
implicitly[AnyVal <:< java.lang.Object]  // error
implicitly[AnyRef <:< java.lang.Object]  // ok

However, say you had the following Java class

public class Foo {
    public void bar(Object o) {}
    public void zar(int o) {}
    public void qux(java.lang.Integer o) {}
}

then all of the following would still work when called from Scala

val foo = new Foo
foo.bar(42.asInstanceOf[Int])
foo.bar(42.asInstanceOf[Any])
foo.bar(42.asInstanceOf[AnyVal])
foo.bar(42.asInstanceOf[AnyRef])
foo.zar(42) // zar takes primitive int
foo.qux(42) // qux takes java.lang.Integer

Comments

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.