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'
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
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.
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.
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
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:
Next let's take a look regular pattern matching using Fibonacci as an example
Also the if-else construct returns a value
As a rule of thumb, just remember that you can omit the return statement. Scala will return the last expression in a block statement.
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.
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).
Important side note!! As of Scala 2.9.x you can use the :paste command and everything will work normally.
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:
Preparation:
- Install Typesafe stack
- Install Eclipse Helios or Indigo (I suggest to install Indigo) -
- Install Scala IDE plugin
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}
Subscribe to:
Posts (Atom)

