Learning Scala in 5 parts: Part 2

Let’s create a real application

In part 1 we started writing some lines of code in REPL which is a nice way to get familiar with basic operations in Scala. However, writing software is mostly about creating stand-alone applications that can solve problems for the user, and what you do in REPL disappears once you close the interpreter. This time you’re gonna need a larger cup of coffee. After this part you will be able to create a simple program which can do any number of the things we showed in part 1 and a few more neat tricks.

Before starting, there are a few concepts we need to understand. The minimum application that can be created uses the following concepts:

  • Object(s)
  • Function(s)

Objects can be seen as a collection of values and functions.
Functions you already know from basic math. Sine, cosine and logarithm are some functions known to most people. These functions are similar because they require one input argument and return a single value as the answer when you apply them. Functions can have 0 or more arguments, but functions can return at most 1 value. To make things more confusing, the 1 value returned by a function can be a list of values. Functions that return nothing usually exist because of their side effects, for example printing things to the screen (in part 1, we saw println(…) as an example of this).

To create this application, first create a file called Minimum.scala and save it somewhere. Open the file with your text-editor and type in the following program:

When you have saved the above program as Minimum.scala, we are ready to run it. Open a terminal and navigate to the folder where the file is residing and type:

Now that was certainly underwhelming, right? Nothing happened. Let’s find out why! The program starts by defining an object called Minimum. This is just a name we chose to describe what it contains. Everything within the brackets following the name is inside this object. In our case, a single function, main which takes 1 argument and returns nothing. main is the mandatory name for an entry point in a program. The program starts execution by calling the main function with any arguments we supplied in the terminal. The main function is empty, so it does nothing. Programs finish once the main function finish execution (with some exceptions that are outside the scope of this tutorial).

Compilation is good

To make this program readily available, we can compile it. The what, how and why of compilation is outside the scope of this tutorial and requires some technical understanding to grasp, but suffice to say that every program worth anything should be compiled in the end such that it can be used by anyone who doesn’t have the source code of the program. To compile and run the program type the following in the console:

Notice that the first time you compile the program like this it takes a short wile to finish. If you try it again it will be faster because of the way fsc (fast scala compiler, yes it’s true!) works. You can also use the command scalac, but it’s slow and wont speed up after using it once. Take notice that running the compiled object requires that you don’t put .scala after the object name. Also notice that the compiler creates .class files in the folder when you compile the program. Finally, when you run the compiled program it is faster than running the uncompiled program with scala Minimum.scala.

Do something

Change your program to the following:

and run the following command in the terminal:

We gave 3 arguments to the program. This means you can actually view your program as a function which takes arguments and this is basically exactly what it is.

The arguments are always located inside the args array. Then we run the foreach method on args and pass to it a function which we want to be done on each argument. In this case, we gave it a single argument function, so foreach knows how to apply it on each element. The result is that the program printed each argument. This is silly you say, but a program with similar functionality actually comes shipped with Ubuntu, it’s called echo and works like so:

The program can also be written in a more verbose way as:

Do something interesting

Let’s make a program that checks which arguments end with the letter ‘e’. To do this, we can create a function that checks a string to see if it ends with ‘e’ and answers either true or false. If we apply this function on each argument to our program, we get what we want.

Consider the following program:

The function we introduced is called endsWithE and accepts only a single argument of the type String. Scala can automatically see that we return only true or false, and therefore we don’t have to tell it anything about the return type of this function. However, using the “=” equality sign, we tell it that it does indeed return something!
Following the equality we call the function “last” on the input string which gets the last character and then we use what is called pattern matching. Simply put, pattern matching allows us to execute some code depending on which pattern an object matches.
We only have two cases, either the last character matches the pattern ‘e’, in which case we give the value true, otherwise it will match the wildcard pattern ‘_’ and yield false.

The main function has also been changed to take advantage of our new function. It now introduces a value named withE and sets it to be the value of endsWithE mapped on the entire argument array. This means that we get a list of the same length with the result of using the function on each element.

We can present the results together with the original value by using zip which creates a list with the combination of elements from both lists. A list of 2-tuples. You can think of tuples as a list where elements can have different types. So zipping the arguments with the results we get a list of tuples which we can print out.

Compiling and running the program looks as follows:

The function endsWithE(str:String) could be rewritten as:

Which means return true iff the last character in str is equal to ‘e’. Behind the scenes, this is really calling a function called equals on the last character with ‘e’ as input, thus we can rewrite to:

In fact, the function can be removed altogether:

Removed might be a strong word, and the keen eye has already spotted that we simply moved the function directly into the map function at line 4. This is a common trick in Scala and other functional languages and is usually called anonymous functions. In this example it is quite clear why this name is used since we explicitly removed the definition of endsWithE(…), and thus we removed the identifier.

We can also drop the definition of the value withE, which leaves us with this little piece of program with exactly the same functionality as before:

Which version is more readable? Which version do you prefer?

It’s probably an object!

There are probably tons of things you didn’t understand fully about the things presented so far. Don’t worry, here comes a golden rule of thumb. The key to scala is that everything is an object. As already stated, objects are collections of some values and more importantly functions.
Look at this line again:

args is an object. zip is a function on that object. Get ready for a bomb shell: functions are objects too. Functions are a tiny bit different because they can be applied, but nevermind that. They’re objects all the same. Going further into the line, again, args is still an object and map is a function on args.

Is an anonymous function…also an object! In fact, the .last part is an object which has the == or equals function. ‘e’ is an object. foreach is a function used on the result of the parenthesis. foreach takes a single argument, you guessed it, a function. In this case it is println.

Please keep this in mind, and be curious! Ask yourself what each line means in a program. There are a few exceptions where the compiler does what I call magic, but other than that you will find when you pick a program apart, Scala is just a bunch of objects with functions everywhere.

In the next part I will spend some more time on types and classes while solving the first part of an exam project posted at my university for last year’s introductory programming course. See you soon 🙂

Part 3

CategoriesUncategorized

Leave a Reply

Your email address will not be published. Required fields are marked *