Scala: Overloading Operators

If you come from Java I have just caught your attention. If you are a C++ developer you might be not surprised.

In Scala, every operator is actually a method. The difference between methods and operators is how you use them. When you write:

val = 3 + 5

Scala calls the method + defined in Int:

val = (3).+(5)

In the first example + is used as operator, in the second one, + is used as a method.
As said, every operator is a method, which means that we can call any method as an operator. For instance, this two instructions are equivalent:

val test1 = “Alice” startsWith “A”
val test2 = “Alice”.startsWith(“A”)

After reading this, you might be wondering: Scala doesn’t really have operator overloading, it is only method overloading. Well, maybe it’s true, but from the language point of view, it is operator overloading!

There are three types of operators, infix, prefix and postfix. In Scala you can implement these three kinds, but there are some restrictions about the prefix and postfix operators.

Infix

In infix notation, you put the operator between the objects. This kind of operators could take two or more operators. When having more than two, all but the first go after operator between parenthesis.
Now let’s do a real example where it could be useful this infix operator overloading.

class Angle (d: Int, m: Int, s: Int) { require (d < 360 && m <60 && s < 60) val degree: Int = d val minute: Int = m val second: Int = s def + (that: Angle) : Angle = { val sec = second + that.second val min = minute + that.minute + (sec /60) val deg = degree + that.degree + (min /60) new Angle (deg % 360,min % 60,sec % 60) } def + (deg: Int) : Angle = new Angle (degree + deg % 360, minute, second) def - (that: Angle) : Angle = { val thisSecs = degree * 3600 + minute * 60 + second val thatSecs = that.degree * 3600 + that.minute * 60 + that.second val dif = if(thisSecs <= thatSecs) thisSecs - thatSecs else thatSecs - thisSecs val min = dif / 60 val deg = min /60 new Angle (deg , min % 60, dif % 60) } override def toString = degree+ "º "+minute+"' "+second+"''" }

After creating this class, we can add and subtract angles as follows:

val angle1 = new Angle(40,30,35)
val angle2 = new Angle(30,52,50)
val angle3 = angle1 + angle2
println(angle3)
println(angle1 – angle2)
println(angle2 – angle1)
println(angle3 – angle1)

And the result is:

71º 23′ 25”
9º 37′ 45”
9º 37′ 45”
30º 52′ 50”

This example above is only a proof of concept of operator overloading. Maybe it’s not programmed in a functional way, but I’ve done my best. Any comments are appreciated.

Prefix

In prefix notation, you put the operator before the object. In Scala, the prefix operators can only take one operator, this is called unary operator. The only identifiers that can be used in unary prefix operators are +, , ! and ~. If you need to define a prefix operator, for instance, !, you must implement a method called unary_!.

Postfix

In postfix notation, you put the operator after the object. This kind of operators are also unary. Unlike the prefix operators, in postfix operators there is no restriction about the names of the methods/operators. The convention about postfix operators is invoking the operators without parenthesis only if the operator has no side effects, otherwise, you might include them. For example, method toLowerCase defined in String should be invoked without parenthesis and println() should be invoked with parenthesis because it writes to the Console.

Advertisements

XStream

XStream is a library to serialize objects to XML and vice versa. It must not be used as a XML processor.

The way that XStream serializes and de-serializes objects is by using Annotations. This post will show you how to annotate a class and how to serialize it.

First of all let’s introduce the class:

public class Book { private String isbn; private List author; private String title; private int pages; //class continues... }

This class models a book. It has the ISBN, a list of authors (it’s only a String per author), the title and the number of pages. The point of XStream is that it uses reflection to serialize and de-serialize the objects.
We want to serialize this book to this XML:

<BOOK> <ISBN>978-0-9815316-0-1</ISBN> <AUTHOR>Martin Odersky</AUTHOR> <AUTHOR>Lex Spoon</AUTHOR> <AUTHOR>Bill Venners</AUTHOR> <TITLE>Programming in Scala</TITLE> <PAGES>736</PAGES> </BOOK>

The next step is to annotate the class:

package com.wordpress.j2eethoughts; import com.thoughtworks.xstream.annotations.XStreamAlias; import java.util.List; @XStreamAlias("BOOK") public class Book { @XStreamAlias("ISBN") private String isbn; //no annotations private List author; @XStreamAlias("TITLE") private String title; @XStreamAlias("PAGES") private int pages; //class continues... }

Note that lists must not be annotated. After this, we need to create the facade of XStream:

package com.wordpress.j2eethoughts; import java.util.ArrayList; import java.util.List; import com.thoughtworks.xstream.XStream; public class Main { public static void main(String[] args) { XStream xs = new XStream(); xs.processAnnotations(Book.class); xs.addImplicitCollection(Book.class, "authors", "AUTHOR", String.class); List authors = new ArrayList(); authors.add("Martin Odersky"); authors.add("Lex Spoon"); authors.add("Bill Venners"); Book book = new Book("978-0-9815316-0-1", authors,"Programming in Scala", 736); System.out.println(xs.toXML(book)); } }

And that’s all, now you can serialize any Book object. For de-serialization you must call the method xs.fromXML passing a String to the method.

Scala: Arrays, Lists, Sets and Maps

Despite all Scala code is translated to Java code, there are some differences between Scala Collections and Java Collections. In this post we will try to explain four types of collections: Arrays, Lists, Sets and Maps.

Arrays

In Scala, in contrast to Java, there is an Array object and it can be created in the same way as Java does. However, the syntax differs. The first one is the classical way to create an object.

var classicWay = new Array[String](3)
classicWay(0) = “The”
classicWay(1) = “classic”
classicWay(2) = “way”

There are two important differences to notice. The way to specify the type of the Array is [] instead of <>. The other one is the way to instance the array, in Scala we use the () instead of []. There is also another way to create and initialize an Array, which is less verbose and more compact.

var compactWay = Array(“I”,”like”,”this”,”way”)

As it can be seen, there is no need to specify the type of the Array, the compiler will infer that the type is String. Here there is another difference, we use the companion class to get an instance of Array. Companion classes will be explained in another post, but they can be seen as static classes or utility classes.
Obviously, we can’t access a position of the Array with the [] operator, instead, the () operator is used. For instance:

print(compactWay(1))
compactWay(0) = “We”

It will be transformed into:

print(compactWay.apply(1))
compactWay.update(0,”We”)

Lists

Lists in Scala are always immutable (in Java they can be mutable), they are designed to enable a functional style programming. That means that, once created, a Scala List can’t be modified. But there are operators on Lists, so maybe you would be wondering why there are operators on Lists if they are immutable objects. As in Strings, when you invoke any operation on a List, another List is created and returned when an operator is applied. Maybe, the two main operators are ::: and :: . The first one is the operator for list concatenation. The second one is the operator to prepend an element to a List. Yes, you read it well: prepend (in Scala you can’t append elements to a list). This is because prepend an element at the beginning of a list is a constant-time operation, whereas append is a linear-time operation. Usually, the owner of an operation is the left operand, but in :: the owner is the right operand. Here there are some examples.

val list1 = List(“This”,”is”)
val list2 = List(“a”,”list”)
val list3 = list1 ::: list2
val list4 = “Hey!” :: list3
println(list1)
println(list2)
println(list3)
println(list4)

List1 and list2 remain immutable, they didn’t change. List3 is a new list resulting of concatenating list1 and list2. In list4, the String “Hey!” is prepended to list3. The complete api of List object can be found here.

Sets

There are two kinds of Sets, the immutable and the mutable one. The difference between mutable and immutable objects is that when an object is immutable, the object itself can’t be changed. The most known immutable object in Java is String: once you have created a String, it remains the same until it is destroyed.

By default, Scala uses the immutable Set. If you want to use the mutable Set, you’ll have to import the class. The hierarchy of the Set is the following:

Hierarchy for the Scala Set object

It’s not a problem to change between mutable and immutable collections, since all of them share the same contract. In most cases, no change will be necessary.

You can create a Set in the same way you create a List. The most useful operations are + and +=, but the second one it’s only available in mutable Sets. In the immutable Sets  mySet += “foo”  is transformed to mySet = mySet.+(“foo”). Here there is a simple example of immutable sets:

var trilogies = Set(“The Godfather”, “Lord of the Rings”)
trilogies += “Millennium”
println(trilogies)

In this example, a new Set is created in line 2. If we import the mutable Set, in this same line, the trilogies set will be modified:

import scala.collection.mutable.Set
var trilogies = Set(“The Godfather”, “Lord of the Rings”)
trilogies += “Millennium”
println(trilogies)

Maps

As in Sets, there are two kinds of Maps, the immutable and the mutable ones. The hierarchy of Map is analog to Map’s hierarchy:
Hierarchy of Scala Set
There are two ways to create a Map in Scala, one of them can only be used with the mutable Maps:

import scala.collection.mutable.Map
var steps = Map[Int, String]()
steps += (1 -> “Go straight on”)
steps += (2 -> “Take the second turn on the left”)
steps += (3 -> “It’s opposite the hairdresser”)
println(steps(3))

Obviously, this Map needs to be mutable, because it has been modified since its creation. Ok, we know how to create mutable Maps, but how immutable Maps can be created?

var steps = Map (1 -> “Go straight on”, 2 -> “Take the second turn on the left”, 3 -> “It’s opposite the hairdresser”)
print(steps(3))

Here again, there is no need to specify the type of the Array, the compiler will infer that the type is Int for the keys and String for the values. The operator -> is useful for creating Tuples. A Tuple can be seen as an array of objects, but they don’t need to share the same type.