Showing posts with label Scala. Show all posts
Showing posts with label Scala. Show all posts

Sunday, 13 November 2011

Scala traits

If you are a Java programmer (like me) then you might have used interface. In Java we define an abstract type by using interface. Interface outlines the contract by just having method signature. It does not have any implementation. Traits are similar to interface but it may contain partial implementation.

So what is a trait?

A trait encapsulates the fields and method definitions. It can be mixed into other classes to add new feature or to modify its existing behavior.

Let me give you a simple example how it can be done:

trait DiscountPerson {
 
     def isDiscountApplied() : Boolean
 
     def discountAmount() : Double = 10.5
 
   }

   class Person(age: Int) extends DiscountPerson {
     
      var myAge: Int = age
  
      def isDiscountApplied() = myAge > 60
 
   }

   object DiscountTraitTest extends Application {
  
     val seniorPerson = new Person(65)
  
     if( seniorPerson.isDiscountApplied() ) 
        println(seniorPerson.discountAmount())
   }

If you see carefully you will find that out of two methods in DiscountPerson trait discountAmount method has the implementation and isDiscountApplied method does not have any implementation.

Any other class can extend the DiscountPerson trait and can have different implementation of isDiscountApplied method to get the same amount of discount. This new class does not need to have discountAmount method again to get the same amount discount. So you can see the benefit of using trait - code reusability.

How does trait work?

By this time you already know how you can write a trait in Scala. A trait definition looks like a class definition except that it uses the keyword trait. In the above example the trait is named DiscountPerson. It does not declare a superclass. It means that it has the default superclass of AnyRef.

Once a trait is defined, it can be "mixed in" to a class using either the extends or with keyword. When we use extends keyword to mix in a trait, we implicitly inherit the trait's superclass. In above example, Person subclasses AnyRef (superclass of DiscountPerson) and mixes in DiscountPerson.

It is also possible to mix a trait into a class that explicitly extends a superclass. In this case, extends can be used to indicate the superclass and with to mix in the trait. For Example:

trait Programmer {
 
     def profile(){
        println("I am programmer.")
     }
 
   }

   class Blogger   

   class John extends Blogger with Programmer {
     
     override def toString = "blogger"  
 
   }

The below example will show you how to mix in multiple traits:

trait Programmer {
 
     def profile(){
        println("I am programmer.")
     }
 
   }

   class Blogger 
   
   trait Photographer 

   class John extends Blogger with Programmer 
                              with Photographer {
     
     override def toString = "blogger"  
 
   }

Few more points to note about trait:

1. I have already mentioned that a trait is similar to an interface but it can have implementation. We can also declare fields in a trait. It means that trait can maintain state. In fact, a trait definition can look exactly like a class definition, with two exceptions:

(a) a trait cannot have any "class" parameters

class Person(age: Int)         // will compile

   trait AnotherPerson(age: Int)  // will not compile

(b) in traits "super" calls are dynamically bound whereas in classes they are statically bound. It means that when we write "super.toString" in a class, we know exactly which method implementation will be invoked. But when we define the trait the method implementation to invoke for the "super" call is undefined. Rather, the implementation to invoke will be determined anew each time the trait is mixed into a concrete class.

2. It is possible to add new feature to a class easily using trait.

3. Trait plays an important role in implementing DCI (Data, Context and Interaction) in Scala easily. More you can read from http://www.artima.com/articles/dci_vision.html

When to use trait?

Rules are simple to find out when to use trait:

(a) You might have noticed I used a term called "code reusability". Remember it. If the behavior might be reused in multiple, unrelated classes then you can make it a trait. Trait has the ability to mixed into different parts of the class hierarchy.
Otherwise make it a concrete class.

(b) Second thing to consider is the efficiency. When efficiency is important, it is better to use a class. Traits get compiled to interfaces. So there is a slight performance overhead. However this point should be considered if there is an evidence that trait in question is creating a performance bottleneck and a class can solve the problem.

(c) If you are not sure then start by making it as a trait. You can change it later on.

Conclusion

In this article I have explained the Scala trait - what it is, how it works, how to use them and benefit of using them. Using trait we are actually creating a unit of code that can be reused through inheritance. If we start any of our Scala project with trait then we are keeping more options open before us. I hope that you have enjoyed reading this article. Any comment is welcome.

Sunday, 31 July 2011

Scala - Lists

In this session I am going to tell you about Scala's List. Lists support fast addition and removal of items to the begining of the list, but they do not provide fast access to arbitrary indexes because the implementation must iterate through the list linearly.

Scala's List, scala.List differs from Java's java.util.List type in that Scala Lists are always immutable whereas in Java Lists can be mutable.

Since Lists are immutable in Scala, they behave a bit like Java's strings: when a method is called on a list, it creates and returns a new list with the new value.The immutability of lists helps to develop correct, efficient algorithms bacause it is never needed to make copies of a list.

The below examples show how to create list in Scala:

scala> val capital = List("London", "Delhi");
fruit: List[java.lang.String] = List(London, Delhi)

scala> println(capital)
List(London, Delhi)

scala> val testMatrix =
            List(
             List(1, 0, 0),
             List(0, 1, 0),
             List(0, 0, 1)
         )
testMatrix: List[List[Int]] = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1))

scala> println(testMatrix)
List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1))
  
scala> val empty = List()
empty: List[Nothing] = List()

Lists are homogeneous - the elements of a list all have the same type. The type of a list that has elements of type T is written as List[T].

The list type in Scala is covariant. This means that for each pair of types S and T, if S is a subtype of T, then List[S] is a subtype of List[T].

For Example:

List[String] is a subtype of List[Object].

List[Nothing] is a subtype of every other Scala type. Nothing is the bottom type in Scala's class hierarchy.

Constructing lists

All lists are built from two fundamental building blocks:

(1) Nil =>  represents the empty
(2) : : (pronounced "cons")  =>  the infix operator expresses list extension at the front.

For Example:

 x : : xs represents a list whose first element is x, followed by ( the elements of ) list xs.
 
The above example can be written like this.

scala> val myfruits = "apple" :: ("orange" :: Nil)
myfruits: List[java.lang.String] = List(apple, orange)
  
scala> println(myfruits)
List(apple, orange)

Parentheses can be dropped.

For Example: the below list is same as above:

scala> val myfruits = "apple" :: "orange" :: Nil
myfruits: List[java.lang.String] = List(apple, orange)

Basic Operations on lists

head  =>     returns the first element of a list

tail  =>    returns a list consisting of all elements except the first

isEmpty =>    returns true if the list is empty

scala> myfruits.head
res3: java.lang.String = apple

scala> myfruits.tail
res4: List[java.lang.String] = List(orange)

scala> myfruits.isEmpty
res5: Boolean = false

scala> myfruits.tail.head
res6: java.lang.String = orange

scala> empty.isEmpty
res7: Boolean = true

The head and tail methods are defined for non-empty lists. So when selected from an empty list, they throw an exception.

List Patterns

List(...) can be used to match all elements of a list.

scala> val fruits = List("orange", "apple", "pear")
fruits: List[java.lang.String] = List(orange, apple, pear)

scala> val List(a, b, c) = fruits
a: java.lang.String = orange
b: java.lang.String = apple
c: java.lang.String = pear

In the above example the pattern List(a, b, c) matches lists of length 3, and binds the three elements to the pattern variables a, b, and c.

If the number of list elements is not known beforehand, it is better to match with :: instead.

For Example: the pattern a :: b :: rest matches lists of length 2 or greater.

scala> val e :: f :: rest = fruits
e: java.lang.String = orange
f: java.lang.String = apple
rest: List[java.lang.String] = List(pear)

Concatenating two lists

List has a method named ':::' for list concatenation.

scala> val oneTwo = List(1,2)
oneTwo: List[Int] = List(1, 2)

scala> val threeFour = List(3,4)
threeFour: List[Int] = List(3, 4)

scala> val oneTwoThreeFour = oneTwo ::: threeFour
oneTwoThreeFour: List[Int] = List(1, 2, 3, 4)

Length of a List

scala> List(2, 3, 5).length
res3: Int = 3

It is slower. It traverses the full list to find out the empty list.

Accessing the end of a list: init and last

last returns the last element of a list.

init returns the rest of the list except the last one.

scala> val abcde = List('a', 'b', 'c', 'd', 'e')
abcde: List[Char] = List(a, b, c, d, e)

scala> abcde.last
res0: Char = e

scala> abcde.init
res1: List[Char] = List(a, b, c, d)

Like head and tail, these methods throw an exception when applied to an empty list.

Unlike head and tail, which both run in constant time, init and last need to traverse the whole list to compute their result. They therefore take time proportional to the length of the list.

Reversing a list

reverse method is used to reversing a list.

scala> abcde.reverse
res2: List[Char] = List(e, d, c, b, a)

reverse creates a new list rather than changing the one it operates on. reverse has its own inverse.

scala> abcde.reverse.reverse
res3: List[Char] = List(a, b, c, d, e)

Prefixes and suffixes: drop, take and splitAt

The expression xs take n returns the first n elements of the list xs.

scala> abcde take 2
res4: List[Char] = List(a, b)

The operation xs drop n returns all elements of the list xs except the first n ones.

scala> abcde drop 2
res5: List[Char] = List(c, d, e)

The operation xs splitAt n splits the list at a given index, returning a pair of two lists.

scala> abcde splitAt 2
res6: (List[Char], List[Char]) = (List(a, b),List(c, d, e))

Element selection: apply and indices

apply is used for random element selection.

scala> abcde apply 2
res7: Char = c

apply method is rarely used in Scala because xs apply n takes time proportional to the index n. In fact apply is simply defined by a combination of drop and head.

abcde apply 2 => (abcde drop n).head

indices range from 0 up to the length of the list minus one.

scala> abcde.indices
res8:scala.collection.immutable.Range = Range(0, 1, 2, 3, 4)

Thank you for reading this article. I hope you have enjoyed it.

Friday, 10 June 2011

Scala - tutorial for newbies (Part 2)

This is the next part of this tutorial. In this session I will tell you how to compile Scala program. I will also let you know some more characteristics of Scala. I hope that you will enjoy it. So lets begin.

Scala is a pure object-oriented language. Every value in Scala is an object and every operation is a method call. So when you type 2 + 3 in your Scala interpreter you are actually invoking a method named "+" defined in class Int. With this little bit of Scala knowledge we will try to write and compile our first Scala program.

object HelloWorld {
  def main (args: Array[String]) {
     println("Hello World")
  }
}

Please type the above program in your favorite notepad, save it and give it a name, say HelloWorld.scala. Now it is time to compile the program. We will use scalac for this purpose. Execute the below command in your command prompt:


E:\>scalac HelloWorld.scala

E:\> 


This will generate few class files in your current directory. One of them will be HelloWorld.class. It contains a class which can be directly executed using the scala command.


E:\>scala HelloWorld

E:\>Hello World


If you have done little bit of Java programming before then the above program is not difficult to understand. This program consists of a main method that takes the command line arguments, an array of Strings, as parameter. The main method does not return any value. For this reason there is no declaration of return type. It has a single call to the predefined method println with the friendly greeting as argument.

There are few things to notice in the above program. One of them is object declaration. This declaration introduces singleton object - a class with a single instance. So the above declaration declares both a class called HelloWorld and an instance of that class, also called HelloWorld. The next thing to notice - the main method is not declared as static. In Scala, static members (methods or fields) do not exist. You need to declare these members in singleton objects.

By this time I think you know how to define a function. In Scala, function definition starts with def, then the function's name followed by a comma-sperated list of parameters in parentheses.

Lets try the below example in your scala interpreter.


scala> def min(x: Int, y: Int): Int = {
      |   if( x < y ) x
      |   else y
      | }
 min: (x: Int,y: Int)Int


In the above example, the function named min takes two parameters, x and y, both of type Int. You might have noticed that after the closing parenthesis of min's parameters list there is another : Int type annotation. This defines the result type of the min function. In Java, the type of the value returned from a method is its return type. In Scala it is called result type.

Did you see the equals sign in the above function? It says that a function defines an expression that results in a value. Since the above function contains only one statement, you can leave off the curly braces. It can be written like:


scala>def min2(x: Int, y: Int) = if (x < y) x else y
min2: (x: Int,y: Int)Int


There may be situation when you need to define a method that takes no parameter and returns no value. Here is an example:


scala> def sayHelloToScala() = println("Hello Scala")
sayHelloToScala: ()Unit


Scala interpreter has responded with sayHelloToScala: ()Unit. Here sayHelloToScala is the function's name. The empty parentheses indicate that this function does not take any parameter. Unit is the result type of this function. A result type of Unit indicates function does not return any value. It is similar to Java's void type.

With this I stop for now. Thank you very much for reading it. Please give your feedback.

Sunday, 5 June 2011

Scala - tutorial for newbies (Part 1)

Last couple of days I have been thinking of sharing my Scala notes. I am still in learning phase. So any feedback from you will definitely help me to improve my understanding in Scala. There are many articles available in the Internet about Scala. You can read these articles to know more about Scala. In this article I will tell you how to program in Scala. There will be several parts of this tutorial. This is the first part.

A brief introduction:
  • Scala stands for "scalable language".
  • It is both object-oriented and functional.
  • Java compatible - Scala programs compile to JVM bytecode.
  • Scala program can call Java methods, access Java fields, inherit from Java classes, and implement Java interfaces - good news to Java programmers.
  • Scala is concise, less ceremonies.
  • Scala is statically typed.
  • And it is smart Java.

Please download the latest Scala installation from http://www.scala-lang.org/downloads and follow the instructions suitable for your platform. I will use Scala interpreter to try all the examples. So let start writing some Scala code. In my machine I have Scala 2.8.1.final. If you install Scala correctly and enter "scala" at a command prompt then you should see something like this:

E:\>scala
Welcome to Scala version 2.8.1.final (Java HotSpot(TM) Client VM, Java 1.6.0_23)

Type in expressions to have them evaluated.
Type :help for more information.

scala>

Probably every programmer in this planet started their programming journey by typing "Hello World!". Let me show you how you can do it in Scala.

scala> println("Hello World!")
Hello World!

scala>

I think you probably notice that I haven't typed 'System.out.println("Hello World!")' like Java. I also haven't used any semi-colon ";". By this time I believe you have understood why I said that Scala is concise and less ceremonial. You will see these things more.

Now type 2 + 3.

scala> 2 + 3
res1: Int = 5

In the above figure you will find that an automatic user-defined name "res1" is created and 5 is assigned to it. "res1" means result 1. "Int" indicates integer.

You can use "res1" identifier to do some further programming. For example:

scala> res1 * 4
res2: Int = 20

A new identifier "res2" is created and 20 is assigned to it. The value inside "res1" is not changed, it is still 5. If you type "println(res1)" at your command prompt you will see this.

scala> println(res1)
5

Now it is time to do some experiment with variables. Scala supports two kinds of variables - val and var. A val can never be reassigned if it is already assigned. So it is similar to final variable in Java. But a var can be reassigned. Try these below examples:

scala> val mymsg = "Hello to Scala"
mymsg: java.lang.String = Hello to Scala

A val variable "mymsg" of type java.lang.String is created and "Hello to Scala" is assigned to it. Now if you try to reassign it with a new value you will get an error message.

scala> mymsg = "Good Morning!!"
<console>:6: error: reassignment to val
mymsg = "Good Morning!!"
^

Now if you try the same thing with var variable you will not see any error message.

scala> var mymsg2 = "Hello to Scala"
mymsg2: java.lang.String = Hello to Scala

scala> mymsg2 = "Good Morning"
mymsg2: java.lang.String = Good Morning

If you look carefully in above variable related examples you will find that I haven't specified "java.lang.String" anywhere in my variable definition. This shows Scala's ability to figure out types if you leave off - "type inference".

Few more points before I stop this article for today:

Packages in Scala are similar to packages in Java: they partition the global namespace and provide a mechanism for information hiding.

All of Java's primitive types have corresponding classes in the Scala package.

For Example:

scala.Boolean => Java's boolean
scala.Float => Java's float

Once again thank you very much for reading this article. I hope that you enjoy it and like me you will also keep learning Scala. Any feedback is welcome.