In Scala a function is an object. This can be deduced from the existence of a set of traits called scala.Function, scala.Function1, ... scala.Function22. The traits define the abstract method apply() (I've already written something about it) and some concrete methods. The use of this trait is like this:
object Main extends App { val succ = (x: Int) => x + 1 val anonfun1 = new Function1[Int, Int] { def apply(x: Int): Int = x + 1 } assert(succ(0) == anonfun1(0)) }
This example is taken Scala documentation. What can a function like anonfun1 be useful for? Well, the code shows by itself: succ(0) is equal to anonfun(0). The code of succ and anonfun1 is the same: it takes an Int argument and return an Int which is the argument plus one.
Sometimes Scala can cause you an excruciating confusion, even with the simplest constructs. Would you be able to answer the title question? Why Array(100) is not a new Array(100)?
I've already scraped the surface of companion objects in another post. Companion objects happen to be the reason of the difference between Array(100) and new Array(100). The first translates into a call to Array.apply(100), which is a call to the apply() method of the object Array, the companion of the Array class. As is customary to Scala, the apply() method of a companion object instantiates its class. However the set of parameters is not forced to be the same in length, types of meaning. Actually it happens that the apply() method takes a variable-length list of object to be put inside the newly create Array instance. So:
scala> val a1 = Array(100)
a1: Array[Int] = Array(100)
is equivalent to:
scala> val a2 = new Array[Int](1)
a2: Array[Int] = Array(0)
scala> a2(0) = 100
scala> a2
res1: Array[Int] = Array(100)
Much more compact and quick. The real comfort provided by the companion object' apply() method is:
scala> val a3 = Array(Array(10,20), Array(30,40))
a3: Array[Array[Int]] = Array(Array(10, 20), Array(30, 40))
That's right: I'm talking about Scala classes and their incredible conciseness. It's impossible to look at a class declaration in Scala without appreciating the loathing Scala authors feel for verbosity. Not a single keystroke is wasted in declaring a class like:
scala> class Greetings (var planet: String = "World") {
| def hello { println("Hello " + planet) }
| }
defined class Greetings
scala> val world = new Greetings()
world: Greetings = Greetings@311f56a3
scala> val vulcan = new Greetings("Vulcan")
vulcan: Greetings = Greetings@82f60ce
scala> world.hello
Hello World
scala> vulcan.hello
Hello Vulcan
This is not just a post about arrays, but also tuples and other Scala structures. I've already written about Scala type inference. Well, let's see what happens when one of the element of an Array[Int] is changed into a Double:
scala> val mix = Array(1, 2, 3)
mix: Array[Int] = Array(1, 2, 3)
scala> val mix = Array(1, 2, 3.3)
mix: Array[Double] = Array(1.0, 2.0, 3.3)