Notes of Scala course on Coursera  Week 2 (3)
Here are my notes for the week 2’s lecture of Functional Programming Principles in Scala on Coursera.
1. Functions and Data
1.1 Classes
In Scala, a class ia defined like this:


This definition introduces two entities:
1.2 Objects
We call the elements of a class type objects
.
We create an object by prefixing an application of the constructor of the class with the operator new
.


1.3 Members of an Object
Objects of the class Rational
have two members, numer
and denom
.
We select the members of an object with the infix operator ‘.
’ (like in Java).


1.4 Rational Arithmetic
We can now define the arithmetic functions that implement the standard rules.
1.5 Implementing Rational Arithmetic


1.6 Methods
One can go further and also package functions operating on a data abstraction in the data abstraction itself.
Such functions are called methods.


Remark: the modifier override
declares that toString redefines a method that already exists (in the class java.lang.Object
).
Calling Methods:


Exercise
(1) In your worksheet, add a method neg
to class Rational
that is used like this:


(2) Add a method sub
to subtract two rational numbers.
(3) With the values of x , y , z as given in the previous slide, what is the result of x  y  z
?
Answer


2. More Fun with Rationals
2.1 Data Abstraction
One would expect the rational numbers to be simplified:
 reduce them to their smallest numerator and denominator by dividing both with a divisor.
We could implement this in each rational operation, but it would be easy to forget this division in an operation.
A better alternative consists of simplifying the representation in the class when the objects are constructed:


It is also possible to call gcd in the code of numer
and denom
:


This can be advantageous if it is expected that the functions numer
and denom
are called infrequently.
It is equally possible to turn numer
and denom
into val
s, so that they are computed only once:


This can be advantageous if the functions numer
and denom
are called often.
2.2 The Client’s View
Clients observe exactly the same behavior in each case.
This ability to choose different implementations of the data without affecting clients is called data abstraction.
It is a cornerstone of software engineering.
2.3 Self Reference
On the inside of a class, the name this
represents the object on which the current method is executed.


Note that a simple name x
, which refers to another member of the class, is an abbreviation of this.x
. Thus, an equivalent way to formulate less
is as follows.


2.4 Preconditions
Let’s say our Rational
class requires that the denominator is positive.


require
is a predefined function.
It takes a condition and an optional message string.
If the condition passed to require is false
, an IllegalArgumentException
is thrown with the given message string.
2.5 Assertions
Besides require
, there is also assert
.
assert
also takes a condition and an optional message string as parameters.


Like require
, a failing assert will also throw an exception, but it’s a different one: AssertionError
for assert
, IllegalArgumentException
for require
.
This reflects a difference in intent
require
is used to enforce a precondition on the caller of a function.assert
is used as to check the code of the function itself.
2.6 Constructors
In Scala, a class implicitly introduces a constructor
. This one is called the primary constructor of the class.
The primary constructor
 takes the parameters of the class
 and executes all statements in the class body (such as the require a couple of slides back).
2.7 Auxiliary Constructors
Scala also allows the declaration of auxiliary constructors.
These are methods named this
.


3. Evaluation and Operators
3.1 Classes and Substitutions
We previously defined the meaning of a function application using a computation model based on substitution. Now we extend this model to classes and objects.
Question: How is an instantiation of the class new C(e_1 ,..., e_m)
evaluted?
Answer: The expression arguments e_1 ,..., e_m
are evaluated like the arguments of a normal function. That’s it.
The resulting expresion, say, new C(v_1 ,..., v_m)
, is already a value.
Now suppose that we have a class definition,


where
 The formal parameters of the class are
x_1 ,..., x_m
.  The class defines a method
f
with formal parametersy_1 ,..., y_n
.
(The list of function parameters can be absent. For simplicity, we have omitted the parameter types.)
Question: How is the following expression evaluated?


Answer: The expression new C(v_1 ,..., v_m).f(w_1 ,..., w_n)
is rewritten to:


There are three substitutions at work here:
 the substitution of the formal parameters
y_1 ,..., y_n
of the function f by the argumentsw_1 ,..., w_n
,  the substitution of the formal parameters
x_1 ,..., x_m
of the class C by the class argumentsv_1 ,..., v_m
,  the substitution of the self reference this by the value of the object
new C(v_1 ,..., v_n)
.
3.2 Object Rewriting Examples




3.3 Operators
In principle, the rational numbers defined by Rational are as natural as integers.
But for the user of these abstractions, there is a noticeable difference:
 We write
x + y
, ifx
andy
are integers, but  We write
r.add(s)
ifr
ands
are rational numbers.
In Scala, we can eliminate this difference. We procede in two steps.
Step 1: Infix Notation
Any method with a parameter can be used like an infix operator.
It is therefore possible to write


Step 2: Relaxed Identifiers
Operators can be used as identifiers.
Thus, an identifier can be:
 Alphanumeric: starting with a letter, followed by a sequence of letters or numbers
 Symbolic: starting with an operator symbol, followed by other operator symbols.
 The underscore character ’
_
’ counts as a letter.  Alphanumeric identifiers can also end in an underscore, followed by some operator symbols.
Examples of identifiers:


3.4 Operators for Rationals


Now rational numbers can be used like Int
or Double
:


3.5 Precedence Rules
The precedence of an operator is determined by its first character.
The following table lists the characters in increasing order of priority precedence:

