How to read class/object in Scala documentation - scala

I just learned Scala.
When I read official documentation to look up Array, for example, it has two versions. One is for Class, the other is for Object. I think I know the difference between Class and Object and when I need find methods of Array, I usually go to the Class version. I do not quite know when I need to go to this Object version.It seems when I want to create Multidimensional arrays, I need method(ofDim) in Object version instead of class version. Why?

The identifier Array refers to either the type or its companion object, depending on context.
scala> Array('a', 'b', 'c')
res0: Array[Char] = Array(a, b, c)
res0 is an instance of the Array type. res0 is an object.
scala> Array
res1: Array.type = scala.Array$#1a69136
res1 is the companion object. res1 is an object. It is a singleton, meaning that there are no other objects of its type.
These two objects have different methods on them, because they're very different things.
Instances of the Array type have the methods defined by the class. These are, naturally, the methods that operate on a particular Array instance. For example, the length method returns the length of the array. You need an instance to do this. It wouldn't make sense to write Array.length because that doesn't specify which array you want the length of. But Array('a', 'b', 'c').length is 3.
The companion object has the methods defined by the object. These are the methods that do not require an Array instance. Companion objects will object contain methods that create instances, as is the case for Array. Hence Array.ofDim(2, 2) creates a 2x2 array. That method isn't defined by the class because instances shouldn't have it. For example, it wouldn't make much sense to write Array('a', 'b', 'c').ofDim(2, 2), because the result (an empty 2x2 array) would have nothing to do with the instance that the method was called upon.

As per my understanding, the class defines the actual implementation with methods to operate on the instances (in this case Array - methods like map, count, fold etc.).
The companion object on the other hand provides utility methods for creation (like apply...) (for Array in this case it mostly contains factory methods).

The class methods operate on the class instance data. Like elements of an array for the Array class. The companion object methods usually operate on multiple instances of a class or create one.
The companion objects in Scala play the same role as static members in Java or C#. For example, for Array it mostly contain factory methods. I would not expect to see methods like length or isEmpty on the companion object and on the other hand I would expect to see factory methods on the instance of a class.

Related

Singleton and Companion Objects are made how, are they instances?

I have read how companion and singleton objects can be used to keep static methods, which makes sense. My question is how is this object made or instantiated it? I have read from some sources on how Objects are instances of the class if used as companion objects while others say they are not instances of the class. Then how are the objects existing or being made? Plus the Object would be same class data type I suppose?
My question is how is this object made or instantiated it?
[…]
Then how are the objects existing or being made?
You don't know, shouldn't know, and can't know.
The Scala Language Specification says that they exist. The Scala Language Specification does not say how they are instantiated. Every implementor is free to implement them however they want.
For example, ECMAScript has object literals, so for Scala.js, there is no need for them to be an instance of any class at all. Scala-native is not dependent on any platform, so it can do whatever it wants. Scala-JVM needs to comply with the restrictions of the JVM, where every object needs to be an instance of a class. In Scala-JVM, every singleton object Foo is an instance of a JVM class named Foo$.
Plus the Object would be same class data type I suppose?
The type of a singleton object Foo is the singleton type Foo.type. It's not a class.
I have read from some sources on how Objects are instances of the class if used as companion objects while others say they are not instances of the class.
Instead of reading "some sources", it's much better to just read the source: the Scala Language Specification, specifically section 5.3.2 Case Classes:
A case class definition of 𝑐[tps](ps1)…(ps𝑛) with type parameters tps and value parameters ps implies the definition of a companion object, which serves as an extractor object. It has the following shape:
object 𝑐 {
def apply[tps](ps1)…(ps𝑛): 𝑐[tps] = new 𝑐[Ts](xs1)…(xs𝑛)
def unapply[tps](𝑥: 𝑐[tps]) =
if (x eq null) scala.None
else scala.Some(𝑥.xs11,…,𝑥.xs1𝑘)
}
Each object has its own class, but you can't access the class directly. This class has a constructor without parameters which is called automatically when it's loaded and creates the only instance.
Objects are instances of the class if used as companion objects
Either you misunderstood or you really shouldn't trust these sources. It's possible for a companion object to extend the trait/class it's companion to, but not at all common.
Companion objects are not instances of the class they're companion of, think of them more like a collection of utility methods. If you're familiar with Java - all the method, that you made static in Java (hence they don't belong to a particular instance, but to class in general) would go to Companion object in Scala. Also, companion objects have access to classes private values.
Objects are lazily initialized for you, you don't need to know when and how exactly are they created, just if you call a function from an object - it will be created for you, and there will be only one instance of it.

Quick Documentation For Scala Apply Constructor Pattern in IntelliJ IDE

I am wondering if there is a way to get the quick documentation in IntelliJ to work for the class construction pattern many scala developers use below.
SomeClass(Param1,Parma2)
instead of
new SomeClass(param1,Param2)
The direct constructor call made with new obviously works but many scala devs use apply to construct objects. When that pattern is used the Intelij documentation look up fails to find any information on the class.
I don't know if there are documents in IntelliJ per se. However, the pattern is fairly easy to explain.
There's a pattern in Java code for having static factory methods (this is a specialization of the Gang of Four Factory Method Pattern), often along the lines of (translated to Scala-ish):
object Foo {
def barInstance(args...): Bar = ???
}
The main benefit of doing this is that the factory controls object instantiation, in particular:
the particular runtime class to instantiate, possibly based on the arguments to the factory. For example, the generic immutable collections in Scala have factory methods which may create optimized small collections if they're created with a sufficiently small amount of contents. An example of this is a sequence of length 1 can be implemented with basically no overhead with a single field referring to the object and a lookup that checks if the offset is 0 and either throws or returns its sole field.
whether an instance is created. One can cache arguments to the factory and memoize or "hashcons" the created objects, or precreate the most common instances and hand them out repeatedly.
A further benefit is that the factory is a function, while new is an operator, which allows the factory to be passed around:
class Foo(x: Int)
object Foo {
def instance(x: Int) = new Foo(x)
}
Seq(1, 2, 3).map(x => Foo(x)) // results in Seq(Foo(1), Foo(2), Foo(3))
In Scala, this is combined with the fact that the language allows any object which defines an apply method to be used syntactically as a function (even if it doesn't extend Function, which would allow the object to be passed around as if it's a function) and with the "companion object" to a class (which incorporates the things that in Java would be static in the class) to get something like:
class Foo(constructor_args...)
object Foo {
def apply(args...): Foo = ???
}
Which can be used like:
Foo(...)
For a case class, the Scala compiler automatically generates a companion object with certain behaviors, one of which is an apply with the same arguments as the constructor (other behaviors include contract-obeying hashCode and equals as well as an unapply method to allow for pattern matching).

Apply method for Lists in Scala

I know that Scala List can be created as :
val l = List(1,2,3)
What goes on under the hood when the above statement is executed ?
Is the apply method called here ?
Per the scala documentation : For sequences, apply is positional indexing
http://docs.scala-lang.org/overviews/collections/seqs.html
So , are there 2 apply methods , one for positional indexing & another as the factory method for object creation ?
This invocation actually calls the apply method on the companion object to the List class.
Many scala classes have a companion object, which is a singleton object with the same name as the class. Defining methods on this companion object, is the scala equivalent of java's static methods. It is very common for these companion objects to have one or more apply methods that are used as constructor/factory functions to create an instance of the class. In this case the List object has a method that takes a variable number of arguments of the same type, and creates a List of those objects.
In fact, if you define a case class, scala will automatically define a companion object that, among other things, includes and apply method that takes the same arguments as the case class's constructor, which is why you don't need to use new when constructing case classes.
The list instance also has an apply method, which is used to index into the list, but since it is defined on the List class it only applies to instances of the class, not the object List itself.

Scala Case Classes - Are they just structs?

So I just learned about scala case classes, and I'm told they are used to provide a simple wrapper around a bunch of properties so that it's easier to test for equality. But now I have two questions:
Is this just the same thing as a struct in C++/C#?
Are case classes a value type or a reference type?
First note that a struct in C++ and a struct in C# are very different things.
Structures in C++ are just like regular classes but by default, their members
are public. See this post for more on this topic.
Structures in C# are value types. When passed as a parameter, they are
copied instead of passed via a pointer. This behaviour is similar to a
primitive type in Java. This behaviour is the default in C++, with any
class or struct.
Your second question has been answered in Eric's answer but the important point is that C# structures are passed completely by value (all their fields are copied) while Java/C# classes are passed via a pointer (that is passed by value). See this famous post if you want the full explanation.
Unfortunately, it is not currently possible to have a true value type in JVM bytecode. You cannot make your own type that will be fully copied everytime you pass it. And the answer is no, case classes aren't value types like C# structures. A JVM language may try to replicate the behaviour of a value type but it will be managed by the GC and passed via a pointer (that is passed by value).
To give a more direct answer, no:
Case classes are like regular classes with a few key differences.
Learn more about them on this page.
Not really. What scala case classes are most like is ... scala classes.
They actually are regular scala classes with a few additional methods, that get added to them automatically - namely, .copy on the class itself and .apply and .unapply on the companion object. They also get a nice .toString method, listing all the fields, and .equals, that compares instance members rather than the object ref.
In most other respects, they are just regular scala classes.
Scala classes are just like Java classes. Their reference is passed by value.
Scala case classes are just like scala classes, but some things are automatically generated for you:
The fields of the constructor are publicly accessible (albeit a case class is immutable by default, thus you can regard them as public final values in Java, unless you declare the fields of the case class as var)
An equals and hashCode method based on the fields of the constructor
An apply and unapply method in the companion object
A toString method showing all the values of the constructor
A copy method
Here's an example:
case class MasterOfTheUniverse(name: String, power: Int)
scala> MasterOfTheUniverse("He-Man", 100).name
res1: String = He-Man
scala> MasterOfTheUniverse("He-Man", 100).power
res2: Int = 100
scala> MasterOfTheUniverse("He-Man", 100).toString
res3: String = MasterOfTheUniverse(He-Man,100)
scala> MasterOfTheUniverse("He-Man", 100) == MasterOfTheUniverse("She-Ra", 90)
res4: Boolean = false
scala> MasterOfTheUniverse("She-Ra", 90) == MasterOfTheUniverse("She-Ra", 90)
res6: Boolean = true
scala> MasterOfTheUniverse("He-Man", 100).copy(name = "He-Manatee")
res7: MasterOfTheUniverse = MasterOfTheUniverse(He-Manatee,100)

The difference between 'HashSet' and 'Set' in Scala?

I'm very confused by Scala's HashSet and Set types as they both seem to do the same thing.
What is the difference between them?
Is it the same in Java?
In my reference it says that HashSet is an "explicit set class" (as compared to Set). What does that mean?
Scala's mutable and immutable HashSet implementations are concrete classes which you can instantiate. For example, if you explicitly ask for a new scala.collection.immutable.HashSet, you will always get a set which is implemented by a hash trie. There are other set implementations, such as ListSet, which uses a list.
Set is a trait which all the set implementations extend (whereas in Java, Set is an interface).
Set is also a companion object* with an apply** method. When you call Set(...), you're calling this factory method and getting a return value which is some kind of Set. It might be a HashSet, but could be some other implementation. According to 2, the default implementation for an immutable set has special representation for empty set and sets size up to 4. Immutable sets size 5 and above and mutable sets all use hashSet.
*In Scala, instead of having static class methods, you can create a singleton object with the same name as your class or trait. This is called a companion object, and methods you define on it can be called as ObjectName.method(), similar to how you'd call a static method in Java.
**Set(x) is syntactic sugar for Set.apply(x).