Scala Tutorial Part 2

This is the second part of my tutorial series for Scala. If you haven’t already, be sure to check out the first part. We’re gonna cover declarations, scopes, basic libraries, and a few collections. So, I have you’re ready to get started. Keep in mind, I make the assumption you have a background in coding already, have all the necessary tools already installed and have an idea of what a functional language is. Without further delay, lets get to it!


Object Declarations

Object Declaration

Lets start with the object keyword. We can use this to create a singleton.As you can see on the left, you cannot instantiate an object. The syntax is as follows:
object ObjectName{
 methods
}

This creates an anonymous class, and creates a single instance of it called Square.

Methods are defined using the following syntax:
def methodName(argList):OutputType = expression

Inferred Return Types

You don’t have to specify the OutputType for non-recursive methods, but you should include them anyways, especially for methods where it is not clear what the return type may be. In the example to the left, you have two versions of the same method. They differ in return type only. The first version could infer that the return type is Double. The second version is returning Unit, but if we want Double, this would be a problem. So, be on the safe side: just specify your return type.

In the examples above, we returned values without having to use a return keyword. In Scala, you can still use return, but you do not need to. Methods in
Scala are considered expressions, who’s result is whatever is produced by their last statement. You don’t need to use it even if you’re returning something mid method. Cool right?

Classes and Traits are declared using the following syntax:
(class or trait) ClassName(argumentlist){
 method declarations and variables
}

Obviously, the argumentlist and the brackets around them are optional. I will get into more detail about these in later articles.

Keep in mind, object, class and trait can be declared at the top level in Scala applications. They do not have to be inside something else. Does not mean they can’t be. Basically, still the same rules as Java.

Types in Scala

Now, I want to go over in this section is type declaration. They let you combine multiple types to create a custom alias. They are really useful for shortening code and saving time. Can you imagine typing (Double, Double, Double) a thousand times? Yikes.

Let’s go over scope. Scope in Scala follows the same rules as Java. Scope is limited to the curly braces that surround them, or the block they are defined in. So, nothing new there, assuming you have experience with Java.


Libraries

You have access to all the libraries available to Java, and Scala. This is because Scala code compiles and runs on the JVM. Let’s go over a few.

Quick Note: imports follow similar rules to Java. Instead of a * for importing everything, you use a _.

By default, Scala imports the following libraries for you:
1. import java.lang._ which is imported by default in Java.
2. import scala._ imports everything in scala package, so you do not need to specify the scala prefix later on.
3. import Predef._ which is short for scala.Predef._ and shows that imports are additive.

Because of import 2, we can shorten imports like import scala.io.StdIn._ to import io.StdIn._. Say for instance, you want to import only a few of the features of a package. Using _ would be inefficient. Scala lets you do the following: import io.StdIn.{readInt, readLine} which imports only the methods specified inside the braces.

Selective imports

Say you have two packages with objects that have the same name. Scala has a very simple solution for this: rename or hide certain names. For example: the java.util package contains List, Map, and Set. You can find items with the same names in Scala Collections. Sp, using import java.util._ would be inefficient. So, you could do something like in the image above. We import Java List and rename it as JavaList. Also, we make sure that Map and Set are not imported by setting them to _. The underscore at the end brings all other items from the java.util package without modification.

A Sample Class that gets input
SampleInput usage

Keep in mind, that the () after readLine and readInt are not necessary. But, you should include it because you do not want unexpected side effects.


Basic Collections

In Scala, all collections are part of the standard library. In Java, arrays are post-fixed with [], because they are language-level constructs and not part of the collections library. Let’s start by going over Array, List, and Range. These are ordered sequences of a specific type.

Array and List usage example

Array is a fixed-length, mutable sequence. You can specify type as follows: Array[Type]. List is a immutable sequence. The above code treats List and Array objects as functions, and passes them arguments that are supposed to go into a new collection of that that. The type of the content is easily inferred by Scala. You can easily access elements by their index in both collections. Lastly, remember that Array is mutable and List is immutable. So, you can reassign values in an Array, but if you try the same in a List, you will get an error. I know, its weird that you cannot modify a List like in Java. But, you’ll see the benefits of it later on.

You can create customs using helper methods. I will go over a few of the common ones. Remember, you can use these methods with List and Array.

Array.fill example

As you can see in the above example, you can use the fill method to create Array objects. In the first example, we created an Array with ten 1’s. In the second one, we create an Array with 10 “a”’s. The last example creates an Array with 10 random values between 1 and 0. We use two cool features called currying and pass-by-name here; I will go over these in depth later. Trust me, they’re cool. For now, I will give a simple explanation. Currying is where arguments to a function are passed as separate argument lists instead of
a single, longer argument list. This lets you build partial functions and customize them as needed. Java and Scala are normally pass-by-value. Arguments are evaluated before the function or method is called, and the value it evaluates to is passed in. Using pass-by-name, the code itself is
passed in, and it is re-evaluated every time it is used. You can see this is the last example, which calls math.random as needed. This gives us 10 possibly distinct values instead of just one. Cool right? The only limitation is that the code used to initialize the values does not have any information about the index that the value is going into.

simple tabulate examples
tabulate with a large lambda

You can overcome this limitation with tabulate. This function is very similar to fill, it still curries two argument lists. The first argument is still the length of the collection. The second argument is a function that takes an Int and returns a value. The input value is the index that the function is making the value for. The function that is passed can be a simple lambda expression or a complex one. This method is great if you want the values in the collection to follow a specific pattern.

new operator in Scala

Let’s not forget about the new operator, you can use it to create an Array. It’s not common to use it in Scala, but you can if you want to. Scala developers tend to avoid using the new operator especially with Strings. Remember, the default value for Strings is null, just like in Java. You can’t instantiate a List the same way because List class is abstract.

cons operator example

To create a List, you can use the cons(::) operator. Lists are immutable, so you cannot modify the values or add more. However, it is efficient to make a new List by prepending an element with cons. Nil stands for an empty List; specifically, List[Nothing]. Remember operators are right associative. So, you can group elements together with parenthesis and use the dot operator. The cons operator is great when you want to efficiently build a collection, but don’t know how many elements it will have. If you ahead of time, just use an Array.

example usage of cons

The above code gives you a quick example of how you can use the cons operator to get user input. Remember to use var; if you use val, you cannot modify the list reference. Using cons does not append to the original list, it creates a new one, and val will not allow you to change the reference. We used List[Int]() because if we used Nil, it would not compile. Lastly, we used reverse because cons does a prepend, and list comes out in reverse order. You could just append it, but it’s not efficient. This is not the most efficient solution, obviously. It would be better to just to this whole thing recursively, like in the next figure.

readList with recursion
Range example

Range represents a fixed set of elements. You use these when you use for loops in Scala. The line 1 to 10, is calling the to method of Int on 1 and passing 10 as a parameter. The to method is inclusive, there is an exclusive version called until.


Feel free to play around. Try creating a list of Fibonacci numbers or something. Sky’s the limit. I’ll try to do another entry soon and go over some more useful List and Array methods. So, be on the lookout!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.