Skip to content

Latest commit

 

History

History
239 lines (169 loc) · 17.8 KB

File metadata and controls

239 lines (169 loc) · 17.8 KB

This first session is separated into three worksheets. I recommend you to have a look at some resources I have listed below .

If you are a beginner you can watch this First steps with Scala from the Devoxx 2012. Here are two step-by-step introductions regarding the Scala interpreter for the Scala IDE and in Chapter 2, Programming in Scala you can walk through the interpreter, variables, functions, loops, and iterations.

Worksheets

You can find the Scala Worksheet project on Github. A Worksheet - as stated on their Wiki page is:

'... a Scala file that is evaluated on save, and the result of each expression is shown in a column to the right of your program. Worksheets are like a REPL session on steroids, and enjoy 1st class editor support: completion, hyperlinking, interactive errors-as-you-type, auto-format, etc.'

In the first worksheek I introduce the print line function 'println'.

The println function is a member of the Predef class. As noted here the Predef class is implicitly imported - along with the java.lang and scala package.

The println exercise in the worksheet was easy. But have you tried to nest a println into another println? Like this::

  println(println(1))                             //> 1
                                                  //| ()

It outputs two lines:

1
()

Why is that so? If you look in the ScalaDoc of Predef you find this:

def println(x: Any): Unit 

The result being returned is a singleton object Unit. Unlike Java where a 'void' defines 'nothing is returned' in Scala - being a functional (and object-oriented) language - everything is an object. In fact doing Java calls Scala maps void to an Unit object. An interesting blog aboug 'Void vs Unit' can be found here.

Arithmetic Operators

Like in many other languages you can do arithmetic operations

As you can see the Scala interpreter outputs the result immediately. For educational purpose try playing with brackets like above:

2 + 5 * 8
2 + (5 * 8)
(2 + 5) * 8

I recommend you for each new topic you have learned to experiment with it in a worksheet.

In Scala there are three kinds of calls: infix, unary prefix, and postfix operations.

Infix operations

An infix operator is a method sitting between the object and the parameter(s): https://gist.github.com/taitruong/9486062

Unary prefix operations

A prefix operator is to the left of an operand: https://gist.github.com/taitruong/9486096

Postfix operations

A postfix operator is similar to an infix operator except it is without an argument: https://gist.github.com/taitruong/9486112

All the above mentioned infix, prefix, and postfix operators can alternatively be called in a method style call. In fact, an operator is just another way and syntax how to do a method call. A '1 + 1' is the same when doing a method call '1.+(1)'. If you look in the ScalaDoc for Int you can see that there are several overloaded '+()' methods returning and taking different parameter types like Int, Double, Long, Float, Char. https://gist.github.com/taitruong/9465189

Please note: the methods for prefix operators starts with 'unary_' like 'unary_!'. In Scala there are only four prefix operators: +, -, !, and ~. This means you cannot define a new prefix operator like 'MyClass.unary_=' and use it like '=myClass'.

For further studies have a look at the Scala documentation and Chapter 5 of Programming in Scala, 'Basic Types and Operations'.

'val' and 'var' Variables

worksheet solution

In Scala you can define immutable and mutable variables - also called 'values' and 'variables'. The keyword for an immutable variable is 'val' and 'var' for a mutable variable: https://gist.github.com/taitruong/9465605

In the 2nd line you can see that for the mutable variable the type is not defined - unlike line 1 where 'val immutable: String' is explicitly defined as a String. Scala's compiler uses type inferences. This means that for variable assignments it deduces the type by its initial expression or by the return type of a method.

Compared to Java variable scopes in Scala go even further: https://gist.github.com/taitruong/9465709

Here it is possible to have the same variable name in another scope (here: in the if expression in curled braces). For readability this should be avoided.

For further studies have a look at this nice blog tutorial.

Interlude - Semicolon, parenthesis and curled braces

As you can see you may omit the semicolon at the end of a line. In most cases it is fine to omit it. You can even split up an operator into two lines. Here is an example with the operator 'a = a + 1' in one line: https://gist.github.com/taitruong/9466025

Now I can split the operator into two lines: https://gist.github.com/taitruong/9466102

[Quiz] What is wrong here?

[Answer] Here the line 'if (a < 10) a = a' is interpreted as whole and the next line '+ 1' as a prefix operator. The solution for this is to use parenthesis: https://gist.github.com/taitruong/9466336

For better readability you can use curled braces embracing the if body: https://gist.github.com/taitruong/9466441

The following example might look unusual for you - the curled braces covers the expression and not the whole if body: https://gist.github.com/taitruong/9466514

In the functional paradigm all functions are values and return values. We will cover this topic later when we come to the definitions of a method representing a function. In this example the curled braces embodies lines of code expressions for assigning variable and where the last line as a result is returned and assigned to variable a.

Read further here:

Classes

In its simplest way you can define and instantiate classes like this: https://gist.github.com/taitruong/9466924

Here there is only one constructor defined. It is the primary constructor and in this case it comes with an argument. In Scala you can omit the parentheses for empty constructors and parameterless methods.

A convenient way of defining a class with variables is using this constructor: https://gist.github.com/taitruong/9466991

This way you have defined a class with a primary constructor requiring parameters. If you try to instantiate this class without any param ('new ScalaFun()') you will get a compile error.

For having overloaded constructors you have to define it like this: https://gist.github.com/taitruong/9467067

You can read more about primary and auxiliary constructors in this blog and classes in Odersky's Scala book. In this example there are two points that need to be outlined:

  • Instance variables have to be initialized. A 'var x' instead of a 'var x = 0' will lead into a compile error. If you don't want them to be initialized you need to prefix the class with the keyword 'abstract'.
  • An auxiliary constructors must always call a primary or another auxiliary constructor at first. This ensures the primary constructor to be the sole entry point of the class.

Further you can define default values in a constructor and method: https://gist.github.com/taitruong/9467246

My class in the worksheet solution of this session contains three variables (instance members) and two constructors.

Case Classes

The case class example has been taken and modified from the Scala book: worksheet

As stated in the book:

'... Case classes are Scala's way to allow pattern matching on objects without requiring a large amount of boilerplate. In the common case, all you need to do is add a single case keyword to each class that you want to be pattern matchable.'

In this example we have three case classes ('Var', 'Number', 'VarNumber') derived from the abstract class 'Expr'. The Scala compiler automatically adds three conveniences to a case class:

  1. Factory method: allows to create a case class with 'MyCaseClass()' without the 'new' keyword like 'val myVar = Var("myVar")'.
  2. Val prefix: all parameters get maintained as fields by prefix them with a val. They can then be accessed like 'myVar.name'.
  3. Adds implementations for toString, hash, and equals.

Exercise - A Simple Calculator

In this first exercise you will put altogether you have learned so far. Instead of worksheets you will put your code into classes and objects. You will also define a Scala singleton object with a main method allowing you to start it as a Scala application. Please have a look at the readme.

Exercise 1: Singleton Objects

Scala is compared to Java more object-oriented in that it has no static members (class members) but instance members - instead it has singleton objects: along with the keyword 'class' you can also define an 'object' (readme).

In this exercise this is the first time I define a Scala class instead of working with a worksheet. At the beginning I define a class ScalaFun: FirstStepsExercise01Objects.scala

In Scala it is possible to define several classes and objects in the same file. In my case I define a singleton object ScalaFun: FirstStepsExercise01Objects.scala

In case a class and an object have the same name it is called the companion class and the companion object.

Finally there is another object definition in this file. In this case it is a singleton object without a companion class: FirstStepsExercise01Objects.scala

This standalone singleton object has a main method and allows to run it as a Scala application for example in your Scala IDE. The main method has two lines of code doing the following:

  1. Line 1: a new instance of the companion class ScalaFun is created and assigned to the val 'instance'.
  2. Line 2: the instance is printed using the companion object's member ScalaFun.dateFormat to output the instance' construction time as well.

As a result I get the following output on my console:

> day01session01exercise.first_steps.solution.ScalaFun@5dccb1ae: 11:03:2014 11:46:09:027

Exercise 2: Calculator

This last exercise wraps up your first lesson about arithmetic operations into a singleton: FirstStepsExercise02Calculator.scala

The second singleton allows me to test and output my results: FirstStepsExercise02Calculator.scala

As a result I get this on the console:

6 + 3 = 9.0
6 - 3 = 3.0
6 * 3 = 18.0
6 / 3 = 2.0

Interlude - Implicit Conversions

[Quiz] If you examine the code you might find something interesting: hover over the values of 'a' and 'b' and compare it with the methods where are they are passed to. Do you see the difference?

[Answer] Both values a and b are of type Int and the methods add, subtract, multiply, and divide require Double as input parameters.

How does Scala deal with this? If you look into Int's ScalaDoc you find this:

implicit def int2double(x: Int): Double = x.toDouble

Implicit conversions are one of the most powerful features in Scala. It allows in Scala (as a _sca_lable _la_nguage) to extend existing classes - and not only new ones. In this example the Scala compiler converts these methods calls into the following:

  1. 'add(a,b)' converts to 'add(int2double(a),int2double(b))'
  2. 'subtract(a,b)' compiles to 'subtract(int2double(a),int2double(b))'
  3. 'multiply(a,b)' compiles to 'multiply(int2double(a),int2double(b))'
  4. 'divide(a,b)' compiles to 'divide(int2double(a),int2double(b))'

In the ScalaDoc there is a simple example explaining how to extend Int with a 'times(f: => T)' method allowing to execute any function f times like '5 times println("Hi")'. Here in this 'Baysick' project is a nice example of showing how Scala is extended with the Basic language. There is a similar blog explaining in how to define Basic elements in more detail. You can read more on implicits here and here as well.

Next: Control Structures

Today you have learned that a worksheet is a file that interprets and output your Scala code immediately - like Scala's interpreter. In these worksheets you have make your first steps in doing some arithmetic operations, defining immutable vals and mutable vars. In the exercises you comprehend your Scala know-how including classes and singleton objects in writing a simple calculator.

So far so good. In the next session I will talk about control structures. This covers while loops and for expressions. In the meanwhile you can of course work your way through the next hack session.

Resources

Cheatsheets

First Steps in Scala

Scala Interpreter

Arithmetic operations

Values and Variables

Semicolon Inference

Classes and Case Classes

Singleton Objects