Today I am going to summarize the
chapter 6 of the
Programming in Scala book of
Martin Odersky. This chapter guide you through several technical aspects of Scala, implementing a real example. In concrete implementing the class Rational.
A specification for class Rational
A rational number is a number that can be expressed as a ratio
n/d, where
n and
d are integers, except that
d cannot be zero.
Constructing a Rational
Note that the Scala compiler will compile any code you place in the class body,
which isn't part of a field or a method definition,
into the primary constructor. In our case, every time you construct a Rational a message
"My Rational is created" will be printed.
Another interesting thing is the '
require' method. The '
require' method takes one boolean parameter. If the passed value is true, require will return normally. Otherwise, require will prevent the object from being constructed by throwing an
IllegalArgumentException. The require method belongs to the
Predef object which is imported by default by the Scala compiler.
Finally we added an implementation of the
toString method. By default the toString method prints the memory location where lives the object in the heap.
Adding Rationals
For example, to add
1/2 + 2/3, you multiply both parts of the left operand by 3 and both parts of the right operand by 2, which gives you
3/6 + 4/6. Adding the two numerators yields the result
7/6.
Note that we added two fields named
num and
denom, and initialized them with the values of class parameters n and d. This is because you cannot access in this way :
that.n or
that.d, because
n and
d are in scope in the code of your
+ method, you can only access their value on the object on which
+ was invoked.
With our defined method
+. You can write code like that:
x + y , where x and y and rational objects.
And is equivalent to write that:
x.+(y). Of course, write
x + y is more natural instead of write something like
x.add(y)
Another thing to note, is that it would be great do things like that:
x + x * y , where
x and y are Rationals. Of course is not the same to that :
(x + x) * y than that : x + (x * y). Scala has defined by default rules for
operator precedence and for this reason, expressions involving + , * and / operations on Rationals
will behave as expected.
Auxiliary constructors
Sometimes, you need multiple constructors in a class. In Scala, constructors other than primary constructors are called auxiliary constructors. For example, a rational number with a denominator of 1 can be written more succinctly as simply the numerator. Instead of 5/1, for example, you can just write 5. Therefore instead of write new Rational(5, 1) simply write new Rational(5). But this requires an auxiliary constructor. Auxiliary constructors in Scala start with def this(...).
Method overloading
Now you can add Rationals, but cannot add an Integer and an Rational. For this, we have to overload the method +. Then you could write code like x + 4 , where x is a Rational
Implicit conversions
Now that you can write r + 2, you might also want to swap the operands, as in 2 + r. Unfortunately this does not work yet. Because the Int class doesn't have any method tu add Rationals.
However, there is a way to solve this problem in Scala. You can create an implicit conversion that automatically converts integers to rational numbers when needed. The implicit conversion could be in the companion object.
I hope it was interesting for you, I will try to summarize some interesting chapters of
Programming in Scala, in the next posts.
We keep Scaling!