Don't forget to also checkout my second blog containing articles to all other related ICT topics!!
Showing posts with label Scala. Show all posts
Showing posts with label Scala. Show all posts

Friday, June 15, 2012

Using early member definitions with Traits


scala> :paste
// Entering paste mode (ctrl-D to finish)

trait Environment {
    val mode: String

    override val toString = "Running in mode '" + mode + "'"
}

// Exiting paste mode, now interpreting.

defined trait Environment


scala> val x = new Environment { override val mode = "production" }
x: java.lang.Object with Environment = Running in mode 'null'

//As you can see the mode is still null so instantiating Traits this way is a bad idea.


//You can however use the construct below looking like an anonymous class definition
scala> class Acceptance extends {val mode = "Acceptance"} with Environment
defined class Acceptance

scala> val y = new Acceptance
y: Acceptance = Running in mode 'Acceptance'

//or you can even skip constructing a class and just create a new Object directly
scala> val dev = new {val mode = "Development"} with Environment
dev: java.lang.Object with Environment = Running in mode 'Development'

Monday, June 4, 2012

Micro Scala benchmark

I wanted to check how well Scala performs doing the same test as in Python on my laptop by zipping 2 identical vectors and calculating the sum. It didn't really surprise me that Scala outperformed Python but the outcome really gives me another WTF moment. I probably made a stupid mistake somewhere but just in case here is the test executed on scala. I did a few tests with smaller vectors and those gave the same results with Python and Scala. The strange outcome is due to the result not fitting into an integer !! Changing generic type [Int] to [Long] will result in ouf-of-memory exception unfortunately. For completeness a link to the simple Profiler used.
import Profiler._

object MicroBenchMark extends App {

  val v1 = 1 to 9999999 //scala includes .to(x) while Python excludes .to(x)
  val v2 = 1 to 9999999
  
  def vector_op(vector1: Iterable[Int], vector2: Iterable[Int], op: (Int, Int) => Int): Iterable[Int] = {
       vector1.zip(vector2).map(op.tupled)
  }
  
   profile(println("sum is " +  vector_op(v1, v2, (x,y) => x + y).sum))
   //python prints 99999990000000 instead of 266447232
  
}

sum is 266447232
Execution took 8 seconds

Saturday, May 26, 2012

Using named and default arguments

This time I inlined some comments in REPL output just in case you wondered how that got there.
scala> def orderBigMacMenu(drink: String = "Coke", withMayo: Boolean = true): String = {
     |    /** the meal gets prepared **/
     |    "You ordered BigMac menu with " + drink + (if (withMayo) " with " else " without ") + "mayonaise"
     | }
orderBigMacMenu: (drink: String, withMayo: Boolean)String

scala>

scala>

scala> orderBigMacMenu("drinkA", false)
res4: String = You ordered BigMac menu with drinkA without mayonaise

scala> orderBigMacMenu("drinkB", true)
res5: String = You ordered BigMac menu with drinkB with mayonaise

/** code below works because compiler tries to use arguments provided from left to right 
and "drinkc" is of type String **/
scala> orderBigMacMenu("drinkC")
res6: String = You ordered BigMac menu with drinkC with mayonaise

/** code below fails because compiler tries to use arguments provided from left to right 
and "true" is of type Boolean **/
scala> orderBigMacMenu(true)
:9: error: type mismatch;
 found   : Boolean(true)
 required: String
Error occurred in an application involving default arguments.
              orderBigMacMenu(true)

/** When using named arguments, there is no issue. You can even swap them around if you want to. **/
scala> orderBigMacMenu(withMayo=false)
res8: String = You ordered BigMac menu with Coke without mayonaise

scala> orderBigMacMenu(withMayo=false, drink="Beer")
res9: String = You ordered BigMac menu with Beer without mayonaise

Friday, May 25, 2012

Importance of immutability for concurrency

Let's take a look at how much performance we may gain when applying immutability to our code. I will let the code snippets speak for themselves. Below a generic trait with 3 methods of which two are important: the find and save method.
package robbypelssers.concurrency

trait Store[K,V] {
    def find(k: K): Option[V]
    def save(v: V): Unit
    def getName(): String
}

Now we create a mutable and immutable store (both insert key-value pairs (index mapped to fibonacci number) in respectively a mutable and immutable hashmap.
package robbypelssers.concurrency

import collection.mutable.HashMap

class MutableFibonacciStore extends Store[Int, Int] with Fibonacci {
  
  val store = new HashMap[Int, Int]

  def find(n: Int): Option[Int] = synchronized(store.get(n))

  def save(n: Int): Unit = synchronized(store.put(n, fibonacci(n)))
  
  def getName() = "MutableFibonacciStore"

}

package robbypelssers.concurrency

import collection.immutable.HashMap

class ImmutableFibonacciStore extends Store[Int, Int] with Fibonacci {

  var store = new HashMap[Int,Int]
  
  def find(n: Int): Option[Int] = store.get(n)

  def save(n: Int): Unit = synchronized(store = store + ((n, fibonacci(n))))
  
  def getName() = "ImmutableFibonacciStore"

}

package robbypelssers.concurrency

trait Fibonacci {

    def fibonacci(n: Int): Int = n match {
        case 0 => 0
        case 1 => 1
        case _ => fibonacci(n-2) + fibonacci(n-1)
    }  
  
}

Below a very simple profiler which will give some idea of how long both stores will take to do a lot of calls to find and save.
package robbypelssers.concurrency

import java.util.Date

object Profiler {

  /**
   * profile method works like an Around Advice in AspectOriented programming
   */
  def profile[T](body: => T) = {
      val start = new Date()
      val result = body
      val end = new Date()
      println("Execution took " + (end.getTime() - start.getTime()) / 1000 + " seconds") 
      result
  }
  
}

package robbypelssers.concurrency

import java.util.Date
import Profiler._
object StoreConcurrencyTest extends App {

  val immutableStore = new ImmutableFibonacciStore()
  val mutableStore = new MutableFibonacciStore()
  val numberOfOperations = 40
  
  def useStore(store: Store[Int,Int], n: Int) {
        println("using " + store.getName())
        for (x:Int <- 1 to n) {
              store.save(x)
        }
        for (x:Int <- 1 to n) {
              store.find(x)
        }
  }
  
  profile(useStore(immutableStore, numberOfOperations))
  profile(useStore(mutableStore, numberOfOperations))
  
}

using ImmutableFibonacciStore
Execution took 1 seconds
using MutableFibonacciStore
Execution took 4 seconds

3 golden rules for implementing equality

  • If two objects are equal, they should have the same hashCode. 
  • A hashCode computed for an object won’t change for the life of the object. 
  • When sending an object to another JVM, equality should be determined using attributes available in both JVMs.

Overloading primary constructor in Scala

scala> class Employee(employeeId: Int, isFulltimeEmployed: Boolean) {
     |     /** we can overload the primary constructor **/
     |     def this(employeeId: Int) = this(employeeId, true)
     |     override def toString() = employeeId + " works " + (if (isFulltimeEmployed) "fulltime" else "parttime")
     | }
defined class Employee

scala>

scala> val john = new Employee(12545, true)
john: Employee = 12545 works fulltime

scala> val belinda = new Employee(32567, false)
belinda: Employee = 32567 works parttime

scala> val herman = new Employee(56784)
herman: Employee = 56784 works fulltime

Reference Immutatibility vs object immutability

It's important to understand the difference between immutability of reference and immutability of objects.
scala> class Car(brand:String, year:Int) {
     |      var fuelPercentage = 20
     |      def getBrand() = brand
     |      def getYear() = year
     |      def fillTank(): Unit = fuelPercentage = 100
     |      def getFuelPercentage() = fuelPercentage
     |      override def toString = getBrand() + " from " + year
     | }
defined class Car

scala>

scala> val mycar = new Car("Citroen", 2011)
mycar: Car = Citroen from 2011

scala> mycar.getFuelPercentage()
res2: Int = 20

scala> mycar.fillTank()

scala> mycar.getFuelPercentage()
res4: Int = 100

scala> mycar = new Car("Audi", 2012)
:9: error: reassignment to val
       mycar = new Car("Audi", 2012)
             ^

scala> var hiscar = new Car("Audi", 2012)
hiscar: Car = Audi from 2012

scala> hiscar = new Car("Porsche", 2012)
hiscar: Car = Porsche from 2012

scala>

As you can see mycar is an immutable reference because we used the 'val' keyword. hiscar on the other hand is a mutable reference due to using the keyword 'var'.  Both car objects are mutable. We can fill the tank up and the fuelpercentage will change.

Scala promotes expression oriented programming

Scala promotes immutability and expression-oriented programming. Most scala constructs return a value as we will come to see in following examples.
First let's take a look at type matching:
scala> def replyMessage(message:Any): Any = message match {
     |     case s:String => "Your message is the string " + s
     |     case i:Int => "Your message is the number " + i
     |     case _ => "Your message is of unknown type"
     | }
replyMessage: (message: Any)Any

scala> replyMessage("Hello world")
res1: Any = Your message is the string Hello world

scala> replyMessage(5)
res2: Any = Your message is the number 5

scala> replyMessage(true)
res3: Any = Your message is of unknown type

Next let's take a look regular pattern matching using Fibonacci as an example
scala> def fibonacci(n: Int): Int = n match {
     |     case 0 => 0
     |     case 1 => 1
     |     case _ => fibonacci(n-2) + fibonacci(n-1)
     | }
fibonacci: (n: Int)Int

scala>

scala> (for (n <- 0 to 10) yield fibonacci(n)).toList
res15: List[Int] = List(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55)

Also the if-else construct returns a value
scala> val fname = "Robby"
fname: java.lang.String = Robby

scala> if (fname.startsWith("B")) "Your name does start with B" else "Hey Mr R"
res19: java.lang.String = Hey Mr R

As a rule of thumb, just remember that you can omit the return statement. Scala will return the last expression in a block statement.
scala> def someComplexMethod(n: Int): Int = {
     |     val x = "blabla"
     |     n * 2
     | }
someComplexMethod: (n: Int)Int

scala>

scala> someComplexMethod(3)
res22: Int = 6

Using Scala interpreter from Eclipse

It is possible to use the Scala interpreter from most IDE's. Here is a short description how to use it in Eclipse. You will first need to create a new Scala project however.
  • Window => Open perspective =>  Scala
  • Create new Scala project
  • Window => Show view => Scala interpreter
  • Select the newly created project and press ok
  • Start typing any expression in the Evaluate textbox and press enter

Scala project management and continuous compilation

There are a few ways to manage your Scala projects among to name a few:
Expect more articles about usage some time in the future.

How to workaround Class and Companion object in REPL

As you can see below the companion object can't access the private variable from the Class Person. This is due to a different scope. To fix it you will need to define a container (can be called something else by the way).
scala> class Person {
     | private var firstname = "Robby"
     | private var lastname = "Pelssers"
     | }
defined class Person

scala> object Person {
     | def getFirstName(p: Person) = p.firstname
     | }
:9: error: variable firstname in class Person cannot be accessed in Person
       def getFirstName(p: Person) = p.firstname

scala> object container {
     |   class Person {
     |      private var firstname = "Robby"
     |      private var lastname = "Pelssers"
     |   }
     |
     |   object Person {
     |       def getFirstName(p: Person) = p.firstname
     |   }
     | }
defined module container

scala> import container.Person
import container.Person

scala> val person = new Person()
person: container.Person = container$Person@1a71d29a

scala> Person.getFirstName(person)
res0: java.lang.String = Robby

Important side note!! As of Scala 2.9.x you can use the :paste command and everything will work normally.
scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person {
  private var firstname = "Robby"
  private var lastname = "Pelssers"
}

object Person {
  def getFirstName(p: Person) = p.firstname
}

// Exiting paste mode, now interpreting.

defined class Person
defined module Person

scala> Person.getFirstName(new Person())
res0: java.lang.String = Robby

Scala REPL is smart

Apparently the REPL is smart enough to figure out when you declare a function as it waits for the closing bracket to return. It auto-injects the | for you as you enter new lines. I read that there are a few use cases it can't handle very well yet like defining a class and companion object. Once I've tested this with current version of the REPL I will blog about these cases.
scala> def addTwo(x: Int) = {
     |    x + 2
     | }
addTwo: (x: Int)Int

scala> addTwo(5)
res5: Int = 7

scala>

Playing with the Scala REPL

The first thing you want to verify is that Scala is installed correctly. During installation you get asked if Scala should be added to your path, make sure to do so. If you're working on windows like me, you can now open the command line. Press Start button and type cmd into the 'Search programs and files'. This will open a DOS shell. Next type scala and the REPL (Read Eval Print Loop) will start.
C:\Users\nxp10009>scala
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_30).
Type in expressions to have them evaluated.
Type :help for more information.

scala> "Hello"
res0: java.lang.String = Hello

scala> "Hello".filter(_ != 'l')
res1: String = Heo

scala> 5
res2: Int = 5

Preparing for Scala development

I fell in love with Scala the moment I read 'Programming in Scala' from Martin Odersky, the creator of Scala. Unfortunately at the time being Scala didn't have good tooling support. Neither was it a widely adopted language and as none of my colleagues had any experience yet, it would be risky to start using it. Times have changed and the ecosystem around Scala is blossoming. Typesafe was created in 2011 around basically two stacks, Scala itself and Akka. Meanwhile Typesafe added playframework to its stack. No excuses left for me to keep postponing diving deeper into the internals of Scala and hence I bought 'Scala in depth' this week which I started reading with great interest. Anyway, if you're ready to start exploring the Scala language make sure to keep an eye on this blog ;-)

Preparation:

Sunday, May 6, 2012

Python does not support 'Tail recursion'

Some programming languages support tail recursion for optimizing away tail calls, but Python definitely isn't one of them. Scala on the other hand does.
def fact_using_tailracursion(i):
    def f(n, accumulator): 
        if (n == 0):
            return accumulator
        else:
            return f(n - 1, n * accumulator)
    return f(i,1)

def fact(i):
    if (i <= 0):
        return 1
    else:
        return i * fact(i - 1) 

import cProfile
cProfile.run('fact_using_tailracursion(400)')
cProfile.run('fact(400)')

         404 function calls (4 primitive calls) in 0.236 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.236    0.236 :1()
        1    0.000    0.000    0.236    0.236 t.py:1(fact_using_tailracursion)
    401/1    0.236    0.001    0.236    0.236 t.py:2(f)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


         403 function calls (3 primitive calls) in 0.230 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.229    0.229 :1()
    401/1    0.229    0.001    0.229    0.229 t.py:9(fact)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}