Where is the Object class or java.lang imported into the scala package or Any class? - scala

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?

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.

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

Related

Default implementation of AnyRef.eq method

I am newbie to Scala and exploring the Scala source code to get the concrete understanding. When I refer the scala.AnyRef class to understand the implementation of the eq method, I can see the below definition and it is confusing:
final def eq(that: AnyRef): Boolean = sys.error("eq")
Since this methods throws an error: How and what is the logic eq follows to check that two objects are same? Where can we see that implementation?
The same question applies for hashCode() method.
And why are Any.scala and AnyRef.scala not part of Scala package? I can see only AnyValues.scala.
This implementation is not really used; it's a stub. The compiler replaces calls to this method by logic of its own. The actual implementation is therefore buried deep inside the compiler.
Any.scala and AnyRef.scala do not have a physical existence either for the same reasons. They are magically materialized by the compiler.
In general, you cannot gain much knowledge from the source code of the primitive types (other examples: Int, Nothing, etc.).

Why does the Scala API have two strategies for organizing types?

I've noticed that the Scala standard library uses two different strategies for organizing classes, traits, and singleton objects.
Using packages whose members are them imported. This is, for example, how you get access to scala.collection.mutable.ListBuffer. This technique is familiar coming from Java, Python, etc.
Using type members of traits. This is, for example, how you get access to the Parser type. You first need to mix in scala.util.parsing.combinator.Parsers. This technique is not familiar coming from Java, Python, etc, and isn't much used in third-party libraries.
I guess one advantage of (2) is that it organizes both methods and types, but in light of Scala 2.8's package objects the same can be done using (1). Why have both these strategies? When should each be used?
The nomenclature of note here is path-dependent types. That's the option number 2 you talk of, and I'll speak only of it. Unless you happen to have a problem solved by it, you should always take option number 1.
What you miss is that the Parser class makes reference to things defined in the Parsers class. In fact, the Parser class itself depends on what input has been defined on Parsers:
abstract class Parser[+T] extends (Input => ParseResult[T])
The type Input is defined like this:
type Input = Reader[Elem]
And Elem is abstract. Consider, for instance, RegexParsers and TokenParsers. The former defines Elem as Char, while the latter defines it as Token. That means the Parser for the each is different. More importantly, because Parser is a subclass of Parsers, the Scala compiler will make sure at compile time you aren't passing the RegexParsers's Parser to TokenParsers or vice versa. As a matter of fact, you won't even be able to pass the Parser of one instance of RegexParsers to another instance of it.
The second is also known as the Cake pattern.
It has the benefit that the code inside the class that has a trait mixed in becomes independent of the particular implementation of the methods and types in that trait. It allows to use the members of the trait without knowing what's their concrete implementation.
trait Logging {
def log(msg: String)
}
trait App extends Logging {
log("My app started.")
}
Above, the Logging trait is the requirement for the App (requirements can also be expressed with self-types). Then, at some point in your application you can decide what the implementation will be and mix the implementation trait into the concrete class.
trait ConsoleLogging extends Logging {
def log(msg: String) = println(msg)
}
object MyApp extends App with ConsoleLogging
This has an advantage over imports, in the sense that the requirements of your piece of code aren't bound to the implementation defined by the import statement. Furthermore, it allows you to build and distribute an API which can be used in a different build somewhere else provided that its requirements are met by mixing in a concrete implementation.
However, there are a few things to be careful with when using this pattern.
All of the classes defined inside the trait will have a reference to the outer class. This can be an issue where performance is concerned, or when you're using serialization (when the outer class is not serializable, or worse, if it is, but you don't want it to be serialized).
If your 'module' gets really large, you will either have a very big trait and a very big source file, or will have to distribute the module trait code across several files. This can lead to some boilerplate.
It can force you to have to write your entire application using this paradigm. Before you know it, every class will have to have its requirements mixed in.
The concrete implementation must be known at compile time, unless you use some sort of hand-written delegation. You cannot mix in an implementation trait dynamically based on a value available at runtime.
I guess the library designers didn't regard any of the above as an issue where Parsers are concerned.

In Scala, what is an "early initializer"?

In Martin Odersky's recent post about levels of programmer ability in Scala, in the Expert library designer section, he includes the term "early initializers".
These are not mentioned in Programming in Scala. What are they?
Early initializers are part of the constructor of a subclass that is intended to run before its superclass. For example:
abstract class X {
val name: String
val size = name.size
}
class Y extends {
val name = "class Y"
} with X
If the code was written instead as
class Z extends X {
val name = "class Z"
}
then a null pointer exception would occur when Z got initialized, because size is initialized before name in the normal ordering of initialization (superclass before class).
As far as I can tell, the motivation (as given in the link above) is:
"Naturally when a val is overridden, it is not initialized more than once. So though x2 in the above example is seemingly defined at every point, this is not the case: an overridden val will appear to be null during the construction of superclasses, as will an abstract val."
I don't see why this is natural at all. It is completely possible that the r.h.s. of an assignment might have a side effect. Note that such code structure is completely impossible in either C++ or Java (and I will guess Smalltalk, although I can't speak for that language). In fact you have to make such dual assignments implicit...ticilpmi...EXplicit in those languages via constructors. In the light of the r.h.s. side effect uncertainty, it really doesn't seem like much of a motivation at all: the ability to sidestep superclass side effects (thereby voiding superclass invariants) via ASSIGNMENT? Ick!
Are there other "killer" motivations for allowing such unsafe code structure? Object-oriented languages have done without such a mechanism for about 40 years (30-odd years, if you count from the creation of the language), why include it now?
It...just...seems...dangerous.
On second thought, a year layer...
This is just cake. Literally.
Not an early ANYTHING. Just cake (mixins).
Cake is a term/pattern coined by The Grand Pooh-bah himself, one that employs Scala's trait system, which is halfway between a class and an interface. It is far better than Java's decoration pattern.
The so-called "interface" is merely an unnamed base class, and what used to be the base class is acting as a trait (which I frankly did not know could be done). It is unclear to me if a "with'd" class can take arguments (traits can't), will try it and report back.
This question and its answer has stepped into one of Scala's coolest features. Read up on it and be in awe.

What compromises Scala made to run on JVM?

Scala is a wonderful language, but I wonder how could be improved if it had it's own runtime?
I.e. what design choices were made because of JVM choice?
The two most important compromises I know about are:
type erasure ("reflecting on Type"): It has to manage a Manifest to get around the Java compilation (independent of the JVM, for backward compatibility reason).
collection of primitive type: e.g.: arrays
new scheme of handling arrays in Scala 2.8. Instead of boxing/unboxing and other compiler magic the scheme relies on implicit conversions and manifests to integrate arrays
Those are the two main JVM limitations, when it comes to manage generic type (with bounds): The Java JVM does not keep the exact type use in a generic object, and it has "primitive" types.
But you could also consider:
Tail-call optimization is not yet full supported by the JVM, was hard to do anyway (and yet Scala 2.8 introduces the #tailrec annotation)
UAP (universal Access Principle) needs to be emulated (not supported by Java), and will be soon completed for Value Holder (#proxy)
the all mix-in mechanism needs also to be emulated
more generally, the huge number of static types introduced by Scala need (for most of them) to be generated in Java:
In order to cover as many possibilities as possible, Scala provides:
Conventional class types,
Value class types,
Nonnullable types,
Monad types,
Trait types,
Singleton object types (procedural modules, utility classes, etc.),
Compound types,
Functional types,
Case classes,
Path-dependent types,
Anonymous types,
Self types,
Type aliases,
Generic types,
Covariant generic types,
Contravariant generic types,
Bounded generic types,
Abstract types,
Existential types,
Implicit types,
Augmented types,
View bounded types, and
Structural types which allow a form of duck typing when all else fails
This article is a discussion with Martin Odersky (Scala's creator) and includes the compromises that were made in Scala for compatibility with Java. The article mentions:
Static overloading of methods
Having both traits and classes
Inclusion of null pointers.
Less an issue with the runtime than a cultural hangover: universal equality, hashing, toString.
More deeply tied to the VM: strict by default evaluation, impure functions, exceptions.

What are the relationships between Any, AnyVal, AnyRef, Object and how do they map when used in Java code?

I usually end up trying every combination until it compiles. Can somebody explain what I should use where?
I'll disagree with Chris's answer in one regard. The classes Any, AnyRef and AnyVal are classes. But they don't appear as classes in bytecode, because of intrinsic limitations of the JVM.
This arises out of the fact that not everything in Java is an object. In addition to objects, there are primitives. All objects in Java are descendant from java.lang.Object, but primitives are set apart and, presently*, not extensible by a programmer. Note also that primitives have "operators", not methods.
In Scala, on the other hand, everything is an object, all objects belong to a class, and they interact through methods. The JVM bytecode generated does not reflect this, but that doesn't make them any less so, just as Java has generics, even though the bytecode doesn't have them.
So, in Scala, all objects are descendant from Any, and that includes both what Java considers objects and what Java considers primitives. There's no equivalent in Java because there is no such unification.
Everything that is considered a primitive in Java is descendant from AnyVal in Scala. Until Scala 2.10.0, AnyVal was sealed, and programmers were unable to extend it. It should be interesting to see what will happen with Scala on .Net, since interoperability alone calls for Scala to at least recognize user-defined "primitives".
Also extending Any is AnyRef, which is equivalent to java.lang.Object (on the JVM at any rate).
Up to Scala 2.9.x, a user could not extend Any or AnyVal, nor reference them from Java, but there were other uses they could be put to in Scala. Specifically, type signatures:
def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)
What each means should be obvious from the class hierarchy. Of note, however, is that f and h will auto-box, but g will not. That is a bit the opposite of what Java does, in that f and h cannot be specified, and g (defined with java.lang.Object) would cause auto-boxing.
Starting with Scala 2.10.0, though, the user can extend AnyVal or Any, with the following semantics:
If a class extends AnyVal, no instance will be created for it on the heap under certain conditions. This means the fields of this class (on 2.10.0 only a single field is allowed -- whether that will change remains to be seen) will stay on the stack, whether they are primitives or references to other objects. This allows extension methods without the instantiation cost.
If a trait extends Any, then it can be used with both classes that extend AnyRef and classes that extend AnyVal.
PS: In my own view, Java is likely to follow C# in allowing "struct" primitives, and maybe typedefs, as parallelism without resorting to them is proving difficult to accomplish with good performance.
Seen this? The text of the page has some java interoperability remarks.
http://www.scala-lang.org/node/128
Any and AnyVal are, I believe, part of the scala type system and are not classes as such (in the same way that Nothing is a type, not a class). You cannot use them explicitly from within Java code.
Howwever, in Java/Scala interoperation, a method which accepts a Java Object will expect a scala Any / AnyRef.
What are you actually attempting to do?