Showing posts with label scala. Show all posts
Showing posts with label scala. Show all posts

Tuesday, April 6, 2010

Generic Matrix[T] impl in Scala v2.8+

This is my attempt to learn how to implement generic math libraries(generic in the sense that they can work with any "Numeric" type such as Int,Long,Double,...etc) in Scala. Similar efforts have been tried at following places..

http://stackoverflow.com/questions/485896/how-does-one-write-the-pythagoras-theorem-in-scala
http://dcsobral.blogspot.com/search/label/matrix

I got enough guidance from scala community here, and from this write-up[warn: PDF] on new array impl in scala v2.8 .

Here is the result...


//Generic Rep for m X n immutable matrix
class Matrix[T: ClassManifest] private (private val elems: Array[Array[T]])(n: Numeric[T]) {

import n.mkNumericOps

val rows = elems.size //Returns # of rows
val cols = elems(0).size //Returns # of cols

//Returns jth elem in ith row
// 0 <= i < rows And 0 <= j < cols
def apply(i: Int, j: Int): T = elems(i)(j)

//Returns ith row, 0 <= i < rows
def row(i: Int): Array[T] = elems(i).clone

//Returns ith col, 0 <= i < cols
def col(i: Int): Array[T] = elems.map(_(i))

def *(that: Matrix[T]): Matrix[T] = {
if(this.cols != that.rows)
throw new IllegalArgumentException("Can't be multiplied")
else {
val newArr = Array.ofDim[T](this.rows, that.cols)

for(i <- 0 to this.rows-1) {
for(j <- 0 to that.cols-1) {
newArr(i)(j) = this.row(i).zip(that.col(j)).map(a => a._1 * a._2).sum(n)
}
}
new Matrix(newArr)(n)
}
}

/* ------------ More Matrix Operations ----------- */
}

object Matrix {

def apply[T](elems: Array[Array[T]])(implicit n: Numeric[T],m: ClassManifest[T]): Matrix[T] =
new Matrix[T](clone(elems))(n)

private def clone[T: ClassManifest](arr: Array[Array[T]]): Array[Array[T]] = arr.map(_.clone)
}

Monday, February 22, 2010

QuickSort in Scala

Today I stumbled on this post, showing Quick-Sort impl in various languages.. and I got the itch to impl a simple version for same in scala. Here is the result..
def quickSort[A](xs: List[A])(implicit orderer:(A)=>Ordered[A]): List[A] =
xs match {
case Nil => xs
case _ :: Nil => xs
case x :: rest =>
quickSort(rest.filter(orderer(_) <= x)) ++ List(x) ++
quickSort(rest.filter(orderer(_) > x))
}
Interesting thing to note is that the size is close to same as the Haskell impl in the mentioned post.

A trial run on the Scala REPL..
Welcome to Scala version 2.7.5.final (Java HotSpot(TM) Client VM, Java 1.6.0_07).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def quickSort[A](xs: List[A])(implicit orderer:(A)=>Ordered[A]): List[A] =
xs match {
case Nil => xs
case x :: Nil => xs
case x :: rest =>
quickSort(rest.filter(orderer(_) <= x)) ++ List(x) ++ quickSort(rest.filter(orderer(_) > x))
}
| | | | | | quickSort: [A](List[A])(implicit (A) => Ordered[A])List[A]

scala> quickSort(List(2,2,2,100,-1,2,5,1,0,3,4,3))
res0: List[Int] = List(-1, 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 100)

scala> quickSort(List("himanshu","ruchi","nitin","manoj"))
res1: List[java.lang.String] = List(himanshu, manoj, nitin, ruchi)

Tuesday, January 26, 2010

An Unbeatable Tic-Tac-Toe (in Scala)

I'm reading AIMA-3e, implemented the AlphaBetaSearch from ch-5 on Adversarial Search. I thought it would be cool to create an actual game, so I wrote a TicTacToe implementation for the game and a game-loop to play it. You can find the code here. If you want to understand the implementation, you know what to read :P.
/** The *Unbeatable* Tic-Tac-Toe game implementation.
*
* Save this script in a file xyz.scala in a directory.
* Compile it with scalac: $scalac xyz.scala
* Play the game with scala: $scala Play
*
* @author Himanshu Gupta
*/

/* A Search algorithm to find the best move
* given current state of the game
*/
object AlphaBetaSearch {
def apply[S,A](state: S, game: ZeroSumGame[S,A]): A = {
val actionMinvalPairs = game.actions(state).map((a) =>
(a,MinValue(game.result(state,a),Math.MIN_DOUBLE,Math.MAX_DOUBLE,game)))
//sort the pairs in descending order of MinValue
val sorted = actionMinvalPairs.sort(_._2 > _._2)
//take the pairs with highest MinValue(they can be more than 1 also)
val bestPairs = sorted.takeWhile(sorted.head._2 == _._2)
//chose randomly one from the best
bestPairs(new scala.util.Random(new java.util.Random).nextInt(bestPairs.length))._1
}

private def MaxValue[S,A](state: S, alpha: Double,beta: Double, game: ZeroSumGame[S,A]): Double =
if (game.terminalTest(state)) game.utility(state)
else {
def loop(states: List[S], v: Double, alpha: Double): Double =
states match {
case s :: rest => {
val tmp = Math.max(v,MinValue(s,alpha,beta,game))
if(tmp >= beta) tmp
else loop(rest, tmp, Math.max(alpha,tmp))
}
case Nil => v
}

loop(game.actions(state).map(game.result(state,_)),Math.MIN_DOUBLE,alpha)
}

private def MinValue[S,A](state: S, alpha: Double, beta: Double, game: ZeroSumGame[S,A]): Double =
if (game.terminalTest(state)) game.utility(state)
else {
def loop(states: List[S], v: Double, beta: Double): Double =
states match {
case s :: rest => {
val tmp = Math.min(v,MaxValue(s,alpha,beta,game))
if(tmp <= alpha) tmp
else loop(rest, tmp, Math.min(beta,tmp))
}
case Nil => v
}

loop(game.actions(state).map(game.result(state,_)),Math.MAX_DOUBLE,beta)
}
}

//abstract game representation
abstract class Game[P,S,A] {
def initialState: S
def player(s: S): P
def actions(s: S): List[A]
def result(s: S, a: A): S
def terminalTest(s: S): Boolean
def utility(s: S, p: P): Double
}

//abstract Two-player game representation
abstract class ZeroSumGame[S,A] extends Game[String,S,A] {

//In two-player, zero-sum games, the two element vector
//can be reduced to a single value because the values
//are always opposite
// -- described in Section 5.2.2
override def utility(s: S, p: String) = utility(s)
def utility(s: S): Double
}
object ZeroSumGame {
val Min = "MIN"
val Max = "MAX"
}

//Tic-Tac-Toe implementation of Two-Player Game
class TicTacToeGame extends ZeroSumGame[(String,Array[Array[Char]]),(Int,Int)] {

type Board = Array[Array[Char]]
type State = (String,Board)
type Action = (Int,Int)

private val X = 'X'
private val O = 'O'
private val nullChar: Char = 0

def initialState = (ZeroSumGame.Max,new Array[Array[Char]](3,3))

def player(s: State) = s._1

def actions(s: State) = {
(for(x <- 0 to 2;
y <- 0 to 2;
if s._2(x)(y) == nullChar) yield (x,y)).toList
}

def result(s: State, a: Action) =
s match {
case (ZeroSumGame.Max, board) =>
if(board(a._1)(a._2) == nullChar) {
val newBoard = cloneBoard(board)
newBoard(a._1)(a._2) = X
(ZeroSumGame.Min, newBoard)
}
else throw new IllegalStateException("Box at " + a + " is already filled.")
case (ZeroSumGame.Min, board) =>
if(board(a._1)(a._2) == nullChar) {
val newBoard = cloneBoard(board)
newBoard(a._1)(a._2) = O
(ZeroSumGame.Max, newBoard)
}
else throw new IllegalStateException("Box at " + a + " is already filled.")
case _ => throw new IllegalStateException("Not a valid player " + s._1)
}

def terminalTest(s: State) =
getWinner(s._2) match {
case Some(_) => true
case None => actions(s).length == 0
}

def utility(s: State): Double =
getWinner(s._2) match {
case Some(ZeroSumGame.Max) => 1.0
case Some(ZeroSumGame.Min) => -1.0
case None if actions(s).length == 0 => 0.5
case _ => throw new IllegalStateException("Not a terminal state." + toString(s))
}

def toString(state: State) = {
val board = state._2
var result = ""
for(y <- 2.until(-1,-1); x <- 0 to 2) {
result = result + (if(board(x)(y) == nullChar) "-" else board(x)(y))
if(x == 2) result = result + "\n"
}
result
}

//Returns the winner if game has terminated without draw,
//None otherwise
private def getWinner(board: Board): Option[String] = {
(for( x <- 0 to 2; y <- 0 to 2) yield board(x)(y)).toList match {
//the for loop results in board charaters at all the
//co-ordinates in following order
//((0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2))

case X :: X :: X :: _ :: _ :: _ :: _ :: _ :: _ :: Nil => Some(ZeroSumGame.Max)
case _ :: _ :: _ :: X :: X :: X :: _ :: _ :: _ :: Nil => Some(ZeroSumGame.Max)
case _ :: _ :: _ :: _ :: _ :: _ :: X :: X :: X :: Nil => Some(ZeroSumGame.Max)
case X :: _ :: _ :: X :: _ :: _ :: X :: _ :: _ :: Nil => Some(ZeroSumGame.Max)
case _ :: X :: _ :: _ :: X :: _ :: _ :: X :: _ :: Nil => Some(ZeroSumGame.Max)
case _ :: _ :: X :: _ :: _ :: X :: _ :: _ :: X :: Nil => Some(ZeroSumGame.Max)
case X :: _ :: _ :: _ :: X :: _ :: _ :: _ :: X :: Nil => Some(ZeroSumGame.Max)
case _ :: _ :: X :: _ :: X :: _ :: X :: _ :: _ :: Nil => Some(ZeroSumGame.Max)

case O :: O :: O :: _ :: _ :: _ :: _ :: _ :: _ :: Nil => Some(ZeroSumGame.Min)
case _ :: _ :: _ :: O :: O :: O :: _ :: _ :: _ :: Nil => Some(ZeroSumGame.Min)
case _ :: _ :: _ :: _ :: _ :: _ :: O :: O :: O :: Nil => Some(ZeroSumGame.Min)
case O :: _ :: _ :: O :: _ :: _ :: O :: _ :: _ :: Nil => Some(ZeroSumGame.Min)
case _ :: O :: _ :: _ :: O :: _ :: _ :: O :: _ :: Nil => Some(ZeroSumGame.Min)
case _ :: _ :: O :: _ :: _ :: O :: _ :: _ :: O :: Nil => Some(ZeroSumGame.Min)
case O :: _ :: _ :: _ :: O :: _ :: _ :: _ :: O :: Nil => Some(ZeroSumGame.Min)
case _ :: _ :: O :: _ :: O :: _ :: O :: _ :: _ :: Nil => Some(ZeroSumGame.Min)

case _ => None
}
}

private def cloneBoard(board: Board): Board = {
val result = new Array[Array[Char]](3,3)
for(x <- 0 to 2; y <- 0 to 2) {
result(x)(y) = board(x)(y)
}
result
}
}

//The-Game-Loop
import java.io.InputStreamReader
object Play {

def main(args: Array[String]) {

println("** Welcome to the *Unbeatable* Tic-Tac-Toe **")
println("")
println("*** How To Play ***")
println("Place an O at the position chosen using its x-y coordinates")
println("0 <= x,y <= 2")
println("")
println("** Let the Game Begin, I place the X first **")

val game = new TicTacToeGame()
val initState = game.initialState
val reader = new InputStreamReader(System.in)

def loop(state: (String,Array[Array[Char]])) {
//display current state of the game
println("")
println("**************")
println(game.toString(state))
println("**************")
println("")

if(game.terminalTest(state)) {
game.utility(state) match {
case 1.0 =>
println("You LOST the game.")
case 0.5 =>
println("Its a DRAW.")
case -1.0 =>
println("You WON the game.")
}
}
else {
//get input
println("** Your turn **")
print("Type x:")
val x = Character.getNumericValue(reader.read())
reader.read() //ignore the new-line char
print("Type y:")
val y = Character.getNumericValue(reader.read())
reader.read() //ignore another new-line char

//validate input
if(x >= 0 && x <= 2 && y >= 0 && y <= 2) {
//play
val nextSt = game.result(state,(x,y))
loop(game.result(nextSt,AlphaBetaSearch(nextSt,game)))
}
else {
println("Invalid Input, Valid Input is 0 <= x,y <= 2")
loop(state)
}
}
}

loop(game.result(initState,AlphaBetaSearch(initState,game)))
}
}
How to Play:
1. Save the above code in a file, let say TicTacToe.scala in a directory.
2. Compile the code by running command $scalac TicTacToe.scala
3. Play the game by running command $scala Play

Have Fun :-)

****************************
I've played it with Scala version 2.7.6.final (Java HotSpot(TM) Server VM, Java 1.6.0_14).

Wednesday, January 13, 2010

scheme like "apply" for scala

(define (m . args) args)
#;> (m 1 2 3)
(1 2 3)
;use apply to provide same arguments stored in a list
#;> (apply m (list 1 2 3))
(1 2 3)
We can do similar thing in scala using something like following...
scala> def m(as: Int*) = as
m: (as: Int*)Int*

scala> m(1, 2, 3)
res0: Int* = Array(1, 2, 3)

If you have a scala Sequence, you can use it as follow..

scala> m(List(1, 2, 3): _*)
res1: Int* = List(1, 2, 3)

scala> m(Seq(1, 2, 3): _*)
res2: Int* = List(1, 2, 3)
Its part of function call syntax as specified in §6.6 of the Scala Reference.

"The last argument in an application may be marked as a sequence argument, e.g. e: _*. Such an argument must correspond to a repeated parameter (§4.6.2) of type S* and it must be the only argument matching this parameter (i.e. the number of formal parameters and actual arguments must be the same). Furthermore, the type of e must conform to scala.Seq[T ], for some type T which conforms to S. In this case, the argument list is transformed by replacing the sequence e with its elements. When the application uses named arguments, the vararg parameter has to be specified exactly once."

Saturday, November 7, 2009

Programming in Scala: Chapter 21 - Implicit Conversions and Parameters

Some notes from chapter-21, Programming in Scala.

Implicits are a way of "adding new methods" to a class. With implicits, you can make one object behave like other.

They are defined like regular methods except that they start with a keyword "implicit".

On finding something like x op y, compiler checks to see if op is defined on x or if there is an implicit converter available such that object returned from convert(x) has op and it replaces x with convert(x).

Rules - Here are 4 rules that govern implicit conversions.

1.Marking Rule: Only definitions marked implicit are available.
Scope Rule: An inserted implicit conversion must be in scope as a single identifier, or be associated with the source or target type of the conversion.

"Single Identifier" means compiler will not try to use someVariable.convert, it has to be available as a single identifier. One usual practice is to define all the implicits in an object Preamble and client code can simply do "import Preamble._" to make all of them available.
However there is one exception to this rule, the compiler will also look for implicit definitions in the companion object of source or target type.For example if you pass a Dollar to a method that expects Euro, compiler will look inside companion objects of Dollar and Euro to see if there is any implicit available to convert Dollar to Euro.

2.Non-Ambiguity rule:
If there are two or more implicits available to do same conversion, compiler will raise an error.

3.One-at-a-time Rule: The compiler will never try to rewrite x + y into convert2(convert1(x))

4.Explicit-First rule: x + y will never be re-written if + is already defined for x.

Note: Usually name of the implicit does not matter.


Where are implicits tried?

They are tried in three places.

1.conversion to an expected type: For example you have a String and you might want to pass it to a function that expects RandomAccessSeq[Char].

2.conversion of the receiver of a selection: If a method is called on an object that doesn't have it for example x + y, if x of a type that doesn't define + then implicits will be tried. One very interesting example of this is in supporting the syntax like.. Map(1 -> "one", 2 -> "two", 3 -> "three"), -> is a method in a class named ArrowAssoc and scala.Predef contains an implicit to do the conversion. Its defined as follow...
package scala
object Predef {
class ArrowAssoc[A](x: A) {
def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
}
implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] =
new ArrowAssoc(x)
...
}

This kind of "rich wrappers" pattern is pretty common in libraries that provide syntax-like extensions to the language.

3.implicit parameters:
You can define method like
def meth(a: A)(implicit b:B, c:C)

You can call meth like a regular method by providing all the parameter list, or you can optionally leave out the whole implicit parameter list as following.
meth(x)

In this case, compiler will look for implicit vals defined of type B,C to insert automatically. So one should make them available like..

implicit val bVal = new B..
implicit val cVal = new C..


As a style rule, it is best to use a custom named type in the types of implicit parameters. For example it is not advised to have following..
def meth(a: A)(implicit b: String)
because String is a very common type and there might be implicit values available of type String that you don't know about so you're better off wrapping the String in a custom type.

View bounds:
Look at the following method...
def maxListImpParm[T](elements: List[T])
(implicit orderer: T => Ordered[T]): T =
elements match {
case List() =>
throw new IllegalArgumentException("empty list!")
case List(x) => x
case x :: rest =>
val maxRest = maxListImpParm(rest)(orderer)
if (orderer(x) > maxRest) x
else maxRest
}

Since orderer is implicit, it can be left out in the method body at both the places and following code means the same..
def maxListImpParm[T](elements: List[T])
(implicit orderer: T => Ordered[T]): T =
elements match {
case List() =>
throw new IllegalArgumentException("empty list!")
case List(x) => x
case x :: rest =>
val maxRest = maxListImpParm(rest) //(orderer) is implicit
if (x > maxRest) x //orderer(x) is implicit
else maxRest
}


Notice, in the second definition, there is no mention of orderer and hence the name does not matter. Since this kind of pattern is very common in scala, scala lets you leave out the name of this parameter and shorten the method header by using a view bound.. above method with new signature will be written as..

def maxListImpParm[T <% Ordered[T]](elements: List[T])

Here [T <% Ordered[T]], means "Any T can be used as long as there is an implicit available to convert it to Ordered[T]". By default an identity implicit converter is always available that would convert Ordered[T] to Ordered[T].


Debugging the Implicits:
Sometimes you might wonder why the compiler did not find an implicit conversion that you think should apply. In that case it helps to write the conversion out explicitly. If that also gives an error message, you then know why the compiler could not apply your implicit.

If above works, then you know one of the other rules(such as scope rule) is preventing the use of converter by the compiler.

When you are debugging a program, it can sometimes help to see what implicit conversions the compiler is inserting. The Xprint: typer option to the compiler/interpreter is useful for this. If you run scalac with this option, then the compiler will show you what your code looks like after all implicit conversions have been added by the type checker.


Caution:
As a word of warning, implicits can make code confusing if they are used too frequently. Thus, before adding a new implicit conversion, first ask whether you can achieve a similar effect through other means, such as inheritance, mixin composition, or method overloading. If all of these fail, however, and you feel like a lot of your code is still tedious and redundant, then implicits might just be able to help you out.

Thursday, November 5, 2009

Programming in Scala: Chapter 20 - Abstract Members

Some notes from chapter-20 of the book "Programming in Scala".

There can be 4 kind of abstract members in a class/trait:
vals (defined using val)
vars (defined using var)
methods (defined using def)
types (defined using type)

Classes can be abstract and traits by definition are abstract, but neither of these are abstract types in scala. An abstract type in scala is always a member of some class/trait.

A parameterless abstract method can be overriden by a val with same name but not viceversa, Why?
"val x" means, once its defined in a concreteObject, then client should get same value whenever concreteObject.x is called, if a parameterless method could override "val x" then that implementation may be such that concreteObject.x is not always the same.

An abstract var:
When you declare a var, you implicitly declare two defs, setter and getter. Notice that following two are same...
trait A {
var x: Int
}


and

trait A {
def x: Int
def x_=: Unit
}


Hence an abstract var can be overriden by a var or two defs.

Initializing abstract vals:

trait A {
val x: Int
val y = { require(x > 0); 1/x }
}


we can create an instance of the anonymous class that mixes above trait by following expression

new A { val x = expr }

Here expr will be evaluated only *after* the class is initialized, during initialization x will have its default value which is zero. So, following fails..

scala> val a = 20
a: Int = 20

scala> new A { val x = 2 * a }
java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:107)
at A$class.$init$(:7)
at $anon$1.(:8)
at .(:8)
at .()
at RequestResult$.(:3)
at RequestResult$.()
at RequestResult$result()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Meth...


To overcome this, we have two ways

Pre-Initialized fields:
It lets you initialize a field of a subclass before the superclass is called. To do this simply place the field definition in braces before the superclass constructor. So this succeeds...

scala> new { val x = 2 * a } with A
res8: java.lang.Object with A = $anon$1@14d6015


pre-initialized fields are not restricted to anonymous classes, they can be used with objects and named classes also as in following example..

scala> object B extends { val x = 2 * a} with A
defined module B

scala> B.x
res9: Int = 40


Note: Because pre-initialized fields are initialized before the superclass constructor is called, their initializers can not refer to the object that is being constructed.

Lazy vals:
If you prefix a val definition with lazy modifier, the initializing expression on the right hand side is evaluated the first time the val is used. So we can redefine trait A as following..
trait A {
val x: Int
lazy val y = { require(x > 0); println("init x"); 1/x }
}


this works now...

scala> new A { val x = 2 * a }
res12: java.lang.Object with A = $anon$1@1b8737f


Caution: if the expression on the right hand side of lazy val produces a side effect, it will happen only once. As soon as the expression is evaluated once, its value will be memoized.

You can neither create an instance of an abstract type nor have an abstract type as a sypertype of another class. A work around is to have an abstract factory method along with the type, whose concrete implementation can create the instances of the concrete type. And, its usually a good idea to have factory methods in separate objects.

You can have a class member and a val member with same identifier in a class. For example, following compiles without any issue.
class A {
class B
val B = 5
}


BTW, if you wanted to refer to class B, you would write A#B and not A.B

Programming in Scala: Chapter 19 - Type Parameterization

Some notes from the chapter-19 from the book "Programming in Scala".

Type parameterization allows you to write generic classes and traits in scala.

Whether a type parameter is covariant, contravatiant or nonvariant, its called parameter's variance.

The + or - symbols, you can place, before the type parameters(to make it covariant,contravariant respectively) are called variance annotations.


In general, If a classes type parameter is also one of the argument's parameter of a method, its not possible to have that parameter covariant. It is not allowed because of being unsafe. See the book for plenty of example describing why.

Methods can also declare type parameters. So we can't have unsafe thing like..
class Queue[+T] {
...
def append(x: T)
}


but, can have
class Queue[T] {
...
def append[U <: T](x: U)
}


This sort of design is called type-driven design, where the type of class/trait "guides" its details and implementation.

Liskov Substitution Principle: In type driven design: it is safe to assume that a type T is subtype of type U if you can substitute a value of type T wherever a value of U is required. The principle holds if T supports all operations that of U and require less but more than the corresponding operation in U.

Note: Queue is not a type but type constructor; Queue[String], Queue[Int] etc are types.

Friday, October 30, 2009

stackable modification with traits

This post just summarises how stackable modification(modifications made to classes by stacking components on top of a class) is done in scala using traits. In traits, super calls resolve dynamically. Following is the example from "Programming in Scala" by Martin Odersky.
abstract class IntQueue {
def get(): Int
def put(x: Int)
}
class BasicIntQueue extends IntQueue {
import scala.collection.mutable.ArrayBuffer
private val buf = new ArrayBuffer[Int]
def get() = buf.remove(0)
def put(x: Int) { buf += x }
}

//trait Doubling extends from IntQueue, this
//means, it can only be mixed with a class
//that also descends from IntQueue
trait Doubler extends IntQueue {

//calls like this are not allowed in normal classes
//here super call will resolve dynamically to the
//trait/class that is in left to this one while mixing
//and gives a concrete implementation to put
abstract override def put(x: Int) { super.put(2 * x) }
}

trait Increment extends IntQueue {
abstract override def put(x: Int) { super.put(x+1) }
}

class MyQ extends BasicIntQueue with Doubler

scala> val q = new MyQ
q: MyQ = MyQ@15bf0c5

//put in Doubler is executed(because its the rightmost component),
//super.put resolves in it
//resolves to put in BasicIntQueue as that is the next concret
//put available to it's left.
scala> q.put(10)

scala> q.put(20)

scala> q.get()
res60: Int = 20 //10 was doubled

scala> q.get()
res61: Int = 40 //20 was doubled

Notice MyQ does nothing else but the mixing only, it has no body. For this we can use the following shorthand code.
val q = new BasicIntQueue with Doubling

Let us check out one more case..
scala> val q = new BasicIntQueue with Incrementer with Doubler
q: BasicIntQueue with Incrementer with Doubler = $anon$1@4cfc65

//rightmost put is applied, which is the put in Doubler, super.put
//in Doubler resolves to put in Incrementer and same in Incrementer
//resolves to put in BasicIntQueue
scala> q.put(10)

scala> q.put(20)

scala> q.get()
res64: Int = 21 //21 = 10*2 + 1

scala> q.get()
res65: Int = 41 //41 = 20*2 + 1

Wednesday, October 7, 2009

scala tidbits

Some notes taken while reading scala code here and there...

***************************************************************************************

In functional way, even setters should return so that you can write code that looks like
return new Account().setBalance(100).setStatus("active")
instead of
Account acct = new Account()
acct.setBalance(100)
acct.setStatus("active")
return acct


***************************************************************************************

@tailrec annotation can be used with method definitions to hint the compiler that implementation is supposed to be tail recursion optimized

***************************************************************************************

I read this code in scala.collections.immutable.Stack class
def pushAll[B >: A](elems: Iterator[B]): Stack[B] =
((this: Stack[B]) /: elems)(_ push _)


It looked so cryptic. Let us see it in pieces

[B >: A] in the type parameter of pushAll means that B has to be a type that A extends.

((this: Stack[B]).. It's simply giving an explicit expected type to an expression (§6.13 of the spec). This is different than a typecast (run-time); if the expression does not conform to the expected type, it will not type-check (compile-time). Lets look at the following example..
scala> trait S
defined trait S

scala> trait T
defined trait T

scala> class A
defined class A

scala> val a = new A with T
a: A with T = $anon$1@fb92dc

scala> (a: S)
:9: error: type mismatch;
found : A with T
required: S
(a: S)
^
scala> a.asInstanceOf[S]
java.lang.ClassCastException: $anon$1
at .(:9)
at .()
at RequestResult$.(<console>:3)
at RequestResult$.(<console>)
at RequestResult$result()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccesso...
scala>


((this: Stack[B]) /: elems)(_ push _)The Iterator doc says that '/:' is a method defined in this class which is same as foldLeft, since method name ends with ':' so (a /: b)(_ push _) is equal to b./:(a)(_ push _), which in turn is same as b.foldLeft(a)(_ push _).

..(_ push _) This is short form of ((x1: Stack[B], x2: B) => x1.push(x2)), I don't exactly know how it works.

***************************************************************************************

We can create classes that are essentially functions as follow..

abstract class Parser[+T] extends (Input => ParseResult[T])

Here Parser is a function, since it is a function it needs to contain the apply method as following(though in this case its automatically inherited from the "super" function)..

def apply(in: Input): ParseResult[T]

***************************************************************************************

Aliasing this
A clause such as “id =>” immediately after the opening brace of a class template defines the identifier id as an alias for this in the class. For example, in
class A { a =>
...
...}

a is equivalent to using this in the class. This helps in situations like following..
class Outer { outer => class Inner { ..we can use outer instead of java style Outer.this here... } }
Above mechanism is loosely equivalent to
val outer = this
except outer.method will not be valid, if method was a private member of Outer class, because outer is just another identifier, while in above case of aliasing that would be allowed.

***************************************************************************************

In pattern matching,a binary pattern like A op B is treated as op(A, B).
Similarly in type parameters, P[A op B] is equal to P[op[A, B]]

***************************************************************************************

There is an interesting way of repeating the string in scala. Look at the following code and see how a string of 5 "x" is composed using "*" on String object.
scala> "x" * 5
res14: String = xxxxx


This is possible in scala because "*" is not an operator(in fact scala *does not* have concept of operators) but just another method defined in RichString class that takes a Int and returns String. In this case scala's way of writing method call in a op b certainly looks pleasing. This reminds me that, in scala, I should *think* about the opportunities of using symbolic method names instead of alphabatic ones wherever operator style method calls can look more meaningful.

Found it through longString method of scala.util.parsing.input.Position .

***************************************************************************************
Extractors
They are a way of wrapping pretty much any data in a way so that pattern matching can be utilized without necessarily making the type of data a case class. This gives one representational independence. In an object, you implement unapply or unapplySeq to make it an Extractors. Many of the collection libraries like List, Array etc provide all the pattern matching functionality using Extractors.

**************************************************************************************

Naming the import:
You can write things like import Fruits.{Apple => McIntosh, Organge} to import just Apple and Orange from Fruits in addition to naming Apple to McIntosh so that we can use McIntosh instead of Apple throughout the code.

**************************************************************************************

Just one observation, scala.List implementation is written heavily in imperative style. May be, the philosophy here is that, what is meant by functional in this context is that for all practical purposes(the external interface used by clients) it is functional but it is OK to write the imperative internal implementation to make it more efficient.

*************************************************************************************

x op= y has a special meaning in scala, it translates into x = x op y provided
1. op= is not defined for x even after trying implicits
2. op is defined for x
3. op is precisely defined in scala specification, but in general it suffices to know its the string of one or more operator characters like +,-,*,++..

*************************************************************************************

Saturday, September 26, 2009

anonymous class in scala

Scala also supports java style syntax of defining anonymous classes. Take a look at this code snippet from Actor companion object definition in Actor.scala from scala actors library.
  /* Notice the argument of actor method, its a
* no-arg(not empty arg list)
* function that returns Unit */
def actor(body: => Unit): Actor = {
/* Here java style syntax of anonymous classes is being used.
* we're creating an instance not of Actor class but a anonymous
* subclass that is implementing a method act() which is declared
* in trait Reactor(also its evident that its not mandatory to use
* keyword override when implementing something from the trait)
* and overriding scheduler. */
val a = new Actor {
def act() = body
override final val scheduler: IScheduler = parentScheduler
}
/* also see that actor is started right here. */
a.start()
a
}

type param in method name in scala

Type parameters can be specified with methods also like in the example below...
scala> def A[a](b:a){ println(b) }
A: [a](a)Unit

scala> A[String]("hi")
hi
scala> A[String](2)
:6: error: type mismatch;
found : Int(2)
required: String
A[String](2)
^

They're being used in receive method in Actor class, lets take a look at the signature of receive
def receive[R](f: PartialFunction[Any, R]):R
The advantage is that we automatically get the type checking done to be sure that return type of receive is gonna be same as the second type parameter of the PartialFunction.

Tuesday, September 15, 2009

SICP Constraint Network Impl code in Scala

I wrote the code for digital circuit simulator from SICP to contrast my scala coding style with that of Martin Odersky(he wrote same in his book "Programming in Scala"). These are the two(part-I, part-II) posts about that.

To enhance my learnings and to write some more code, Now I implemented the constraint propagation network from SICP section-3.3.5 too.

Here is the code...
//all the Constraint implementations
//extend the Constraint class
abstract class Constraint {
def informAboutValue()
def informAboutNoValue()
}

//Connector implementation
class Connector {
private var myName = "Unknown"
private var myVal:Int = _
private var informant:AnyRef = _
private var constraints:List[Constraint] = List()

def this(newName:String) {
this()
myName = newName
}

def name = myName

def hasValue() = informant != null

def value = {
if(!hasValue())
throw new RuntimeException("""|This connector
| does not have a
| value.""".stripMargin)
myVal
}

def setValue(newVal:Int, informer:AnyRef) {
Tuple(hasValue(),newVal == myVal) match {
case Tuple2(false, _) => {
myVal = newVal
informant = informer
constraints.foreach(
(c:Constraint) =>
{ if(c ne informer) c.informAboutValue()})
}
case Tuple2(true,true) => ; //ignore
case Tuple2(true,false) =>
throw new RuntimeException("Contradiction " +
newVal + " " + myVal)
}
}

def forgetValue(retractor:AnyRef) {
if(retractor eq informant) {
informant = null
constraints.foreach(
(c:Constraint) =>
{ if(c ne retractor) c.informAboutNoValue() })
}
}

def connect(c:Constraint) {
constraints = c :: constraints
}
}

//===== Constraints =====
case class Adder(a:Connector,b:Connector,
c:Connector) extends Constraint {
a.connect(this)
b.connect(this)
c.connect(this)

def informAboutValue() {
Tuple(a.hasValue(),b.hasValue(),c.hasValue())
match {
case Tuple3(true,true,false) =>
c.setValue(a.value + b.value, this)
case Tuple3(true,false,true) =>
b.setValue(c.value - a.value, this)
case Tuple3(false,true,true) =>
a.setValue(c.value - b.value, this)
case _ => ; //ignore
}
}

def informAboutNoValue() {
a.forgetValue(this)
b.forgetValue(this)
c.forgetValue(this)
informAboutValue()
}
}

case class Multiplier(a:Connector,b:Connector,
c:Connector) extends Constraint {
a.connect(this)
b.connect(this)
c.connect(this)

def informAboutValue() {
Tuple(a.hasValue(),b.hasValue(),
(a.hasValue() && a.value == 0) ||
(b.hasValue() && b.value == 0),
c.hasValue())
match {
case Tuple4(_,_,true,_) =>
c.setValue(0, this)
case Tuple4(true,true,_,false) =>
c.setValue(a.value * b.value, this)
case Tuple4(true,false,_,true) =>
b.setValue(c.value / a.value, this)
case Tuple4(false,true,_,true) =>
a.setValue(c.value / b.value, this)
case _ => ; //ignore
}
}

def informAboutNoValue() {
a.forgetValue(this)
b.forgetValue(this)
c.forgetValue(this)
informAboutValue()
}
}

case class Constant(value:Int,
c:Connector) extends Constraint {
c.connect(this)
c.setValue(value, this)

def informAboutValue() {
throw new RuntimeException("""|CONSTANT constraint,
| request not allowed
|.""".stripMargin) }
def informAboutNoValue() {
throw new RuntimeException("""|CONSTANT constraint,
| request not allowed
|.""".stripMargin) }
}

case class Probe(c:Connector) extends Constraint {
c.connect(this)

def informAboutValue() {
printProbe(c.value.toString()) }

def informAboutNoValue() {
printProbe("?") }

private def printProbe(value:String) {
println("Probe: " + c.name + " = " + value)
}
}

//====== simulation =====
def celsiusFahrenheitConverter(c:Connector,f:Connector) {
val u = new Connector()
val v = new Connector()
val w = new Connector()
val x = new Connector()
val y = new Connector()

Multiplier(c, w, u)
Multiplier(v, x, u)
Adder(v, y, f)
Constant(9, w)
Constant(5, x)
Constant(32, y)
}

val C = new Connector("Celsius Temp")
Probe(C)
val F = new Connector("Fahrenheit Temp")
Probe(F)

celsiusFahrenheitConverter(C,F)

C.setValue(25, 'user)
//Probe: Fahrenheit Temp = 77
//Probe: Celsius Temp = 25

F.setValue(212, 'user)
//java.lang.RuntimeException: Contradiction 212 77

C.forgetValue('user)
//Probe: Fahrenheit Temp = ?
//Probe: Celsius Temp = ?

F.setValue(212, 'user)
//Probe: Celsius Temp = 100
//Probe: Fahrenheit Temp = 212

Monday, September 14, 2009

SICP digital circuit simulator in scala Part II

Please first read part-I of this post to get the context.

Here I am comparing the differences between my version of the simulator and Martin Odersky's version presented in his book "Programming in Scala" in chapter-18(Stateful Objects).

Overall, It is same as my version(we both are porting the same thing from same source :)). But, yet there are some differences worth noticing..

1. Inside the Simulation class(in my code its the Agenda class), he defines a type
type Action = ()=>Unit
What this does is that it creates an alias Action for the type procedure that takes no arguments and returns Unit. Now he can use Action instead of ()=>Unit everywhere and this enhances readability of the code. I did not know of this concept because its covered in a later chapter(20) in the book and I'm at chapter 18 :).

2. Another trivial difference, He made afterDelay procedure a part of Simulation class itself... I could have done same and its better.

3. He used currying in afterDelay so as to make the calls look as if its a built-in syntax. I don't agree with it... As a code reader I would not want to be confused into understanding a method call as language syntax. But, may be, As I get more experienced with this concept... I'll probably change my stand.

4. Trivial, but he exposes the usage of @unchecked in the match expression when getting next item on the agenda to suppress the warning that case set is not exhaustive as we no for sure that the missing case in question is never gonna happen.

5. Whenever I wrote scala classes and there was a collection(let say List) to be stored, I had two choices...
val l:mutableList
var l:immutableList
Now here is the conflict.. functional style says
- Prefer val over var
- Prefer immutable object over mutable object
As you can see, We can't have both here.
In the Wire class, author choses the second approach of using immutable object with var reference for storing actions. Incidentally I did the same in my code, I was not sure about my decision at the time of doing it but seeing him making the same choice tells me which rule to give preference to in case of conflict :).
However, The reason I chose immutable object was that I felt if its a mutable object and my reference(actions) is exposed publicly, anyone can get hold of it and modify the object(actions List) without Wire knowing about it.

6. The most visible(and important) difference is in the way how he managed agenda items. I implemented it exactly same as in SICP by making Segment(a pair of time, Queue) stored in a priority queue. But, he simplified it. He stored items simply in a single list making sure a new item with smaller(not matching any other item time on the list) time is added before the next later time item in the list. And, a new item is added in the end of other items added for the same time so that they are accessed in FIFO order. Now, accessing the items is so simplified.

7. For constants like delays, he uses the naming convention(described in the book also) of keeping first letter capital as in ConstantVariable.

The biggest learning for me(from point 6), I guess, is that when I port... I more or less map the code from one language to another without changing any implementation detail conceptually. I should actually see if the some implementation detail can be simplified due to new target language features or simply because it can be simplified.

Sunday, September 13, 2009

SICP digital circuit simulator in scala Part I

This is a scala port of digital circuit simulator of section 3.3.4 in SICP. Martin Odersky has done same in Chapter-18(Stateful Objects) in his book Programming in Scala. Before reading his code, I wanted to write it on my own so that I can understand where I don't think *in scala* when writing code in Scala.
Next, I'll read the same port from mentioned scala book and see what I can learn from the differences.

Here is my code(I tested it on Scala version 2.7.5.final interpreter)...

//Segment and Agenda
import scala.collection.mutable.Queue
case class Segment(val time:Int,
val queue:Queue[()=>Unit]) extends Ordered[Segment] {
require(time >= 0)

override def compare(that:Segment) = {
if(that.time == time) 0
else if(that.time < time) -1
else 1
}
}

import scala.collection.mutable.PriorityQueue
class Agenda {
private var currentTime = 0
private val timeSegments = new PriorityQueue[Segment]()

def getCurrentTime = currentTime

def addItem(time:Int, item:()=>Unit) {
getTimeSegment(time) match {
case None =>
val queue = new Queue[()=>Unit]()
queue += item
timeSegments += Segment(time, queue)
case Some(segment) => segment.queue += item
}
}

def propagate():Unit = {
if(!timeSegments.isEmpty) {
firstItem()
propagate()
}
else println("Agenda Propagation Done.")
}

//gets first agenda item and removes it
//from the agenda
private def firstItem = {
val segment = timeSegments.max
currentTime = segment.time

val item = segment.queue.dequeue
if(segment.queue.isEmpty)
timeSegments.dequeue

item
}

//get the Segment matching time from timeSegments
private def getTimeSegment(time:Int) = {
val tmp = timeSegments.filter((s:Segment)=>s.time == time)
if(tmp.isEmpty) None else Some(tmp.first)
}
}

//Wire
class Wire() {
var signal = false
private var actions:List[()=>Unit] = List()

def setSignal(b:Boolean) {
if(b != signal) {
signal = b
//execute all actions
actions.foreach((proc:()=>Unit) => proc())
}
}

def addAction(proc:()=>Unit) {
actions = proc :: actions
proc()
}
}

//Probe
def probe(name:String, wire:Wire, agenda:Agenda) {
wire.addAction(
() =>
println(name + " " + agenda.getCurrentTime
+ " ,New Value = " + wire.signal))
}

//after-delay
def afterDelay(delay:Int, proc:() => Unit, agenda:Agenda) {
require(delay >= 0)
agenda.addItem(agenda.getCurrentTime + delay, proc)
}

//====================== SIMULATION ========================

val theAgenda = new Agenda()
val inverterDelay = 2
val andGateDelay = 3
val orGateDelay = 5

//inverter
def inverter(in:Wire, out:Wire) = {
in.addAction(
() => {
val newVal = !in.signal
afterDelay(inverterDelay, () =>
(out.setSignal(newVal)),theAgenda)
})
"Ok"
}

//and gate
def andGate(in1:Wire, in2:Wire, out:Wire) = {
val action = () => {
val newVal = in1.signal && in2.signal
afterDelay(andGateDelay,
() => (out.setSignal(newVal)),
theAgenda) }
in1.addAction(action)
in2.addAction(action)
"Ok"
}

//or gate
def orGate(in1:Wire, in2:Wire, out:Wire) = {
val action = () => {
val newVal = in1.signal || in2.signal
afterDelay(orGateDelay,
() => (out.setSignal(newVal)),
theAgenda) }
in1.addAction(action)
in2.addAction(action)
"Ok"
}

//half-adder
def halfAdder(in1:Wire, in2:Wire, sum:Wire, carry:Wire) = {
val t1 = new Wire()
val t2 = new Wire()
orGate(in1, in2, t1)
andGate(in1, in2, carry)
inverter(carry, t2)
andGate(t1, t2, sum)
"Ok"
}

// == Running the simulation ==
val in1 = new Wire()
val in2 = new Wire()
val sum = new Wire()
val carry = new Wire()

probe("sum",sum,theAgenda)
//sum 0 ,New Value = false

probe("carry",carry,theAgenda)
//carry 0 ,New Value = false

halfAdder(in1,in2,sum,carry)
//Ok

in1.setSignal(true)

theAgenda.propagate()
//sum 8 ,New Value = true
//Agenda Propagation Done.

in2.setSignal(true)

theAgenda.propagate()
//carry 11 ,New Value = true
//sum 16 ,New Value = false
//Agenda Propagation Done.

Sunday, August 23, 2009

covariance-contravariance and constraining type params

If you define a class saying something like "class Test[A]" in scala then..
  • It is important to notice that Test is not a type but Test[Any] or Test[String] is.
  • At a place where Test[Any] is expected, you can not give Test[String] ... as was my notion due to mostly being a java programmer.
The idea of whether Test[String] should be considered subtype of Test[Any] is called "covariance". Only when you define your class like "class Test[+A]" then Test[String] will be considered subtype of Test[Any] and will be accepted wherever a Test[Any] is needed. '+' indicates that subtyping is covariant(flexible) in that parameter. In java, types are covariant by default.

Contravariance is exactly opposite of covariance and is supported with '-' symbol instead of '+'

Similarly, to constraint type parameters we can say things like...
class MyClass[V <: AnotherType]
This puts the constraint that V has to be a subtype of AnotherType and
class MyClass[V >: AnotherType]
puts the constraint that V has to be a type that is extended by AnotherType

Programming In Scala: Chapter#8-15 notes

Ch8- Functions and Closures
Functions in scala are first class citizens like any other language supporting functional paradigms such as scheme, lisp etc. Which means you can do all the cool abstractions that SICP teaches you.

Function values are objects and hence can be assigned to variables.

*****************************************************************************
"short" forms for writing function values, Let us try to see it through this example..

numbers.filter((x: Int) => x > 0)

We can remove the type parameter types because compiler can infer that from its usage.

numbers.filter((x) => x > 0)

We can remove the parentheses around a parameter whose type is inferred.

numbers.filter(x => x > 0)

You can use '_' as placeholders for one or more parameters as long as each parameter appears *only once* within the function literal. This is also called placeholder syntax.

numbers.filter(_ > 0)

Sometimes placeholder syntax wouldn't work when compiler don't have enough information to infer the missing parameter types. For example val f = _ + _ doesn't compile but val f = (_: Int) + (_: Int) does. Note that first '_' refers to first parameter, second to second parameter and so on.

*****************************************************************************

Partially Applied functions:
Let us see an example..

scala> def sum(a: Int, b: Int, c:Int) = a + b + c
sum: (Int,Int,Int)Int

//Partially apply the method sum on 3,4 , this gives us
//a Partially Applied Function value which takes remaining
//arguments
scala> val a = sum(_: Int, 3,4)
a: (Int) => Int =

//see, we can apply a on one remaining parameter
scala> a(5)
res24: Int = 12

//We can do the partial application also by not supplying
//any param and putting placeholders for all of them
scala> val a = sum(_: Int, _: Int, _: Int)
a: (Int, Int, Int) => Int =

//above scenario can also be written as following. notice '_' in this
//context here does not refer to a single parameter but the whole parameter
//list
scala> val a = sum _
a: (Int, Int, Int) => Int =

scala> a(5,3,4)
res25: Int = 12


If you are writing a partially applied function expression in which you leave off all parameters, such as println _, you can express it more concisely by leaving off the underscore *if function is required at that point* in the code. For example, these three are ok.

numbers.foreach(println _) //note, '_' is not one param but whole param list
numbers.foreach(println)
val a = sum _


but following is not, as its not required at this point in the code.
val a = sum

*****************************************************************************

It supports closures, When a function on calling it returns a function that encloses one or more variable bindings defined in the parent function. These returned functions are called closures(they have bindings closed in them). In general, any function enclosing binding for one or more free variables is a closure. This technique is very powerful and you can do all sorts of data abstractions using them. For a primer on this one should read SICP chapter 3.

Repeated Parameters: def echo(args:String*) means that you can pass 0 or more strings when calling echo and they will be available in the echo definition in an Array[String] named args.

Due to limitation of jvm instruction set, tail-recursion is optimized only for direct tail recursion with the same function. Other indirect tail recursion cases such as mutually recursive functions, it is not optimized.

Ch9- Control Abstraction
Currying: A curried function is applied to multiple argument list instead of one. When you apply a curried function, you actually get multiple(equal to the number of argument lists it has) regular function invocations back to back.
Exp:
def curriedSum(x:Int)(y:Int) = x + y
curriedSum(1)(2) = 3
Basically curriedSum(1) returns a function that is (y:Int)=>1+y and this function is applied on 2.

In any method invocation in scala in which you're passing in exactly one argument, you can opt to use curly braces to surround the argument instead of parentheses. This is provided, so that you could define control abstractions as functions and they can be called with argument in curly braces which looks more like built-in language construct. Though powerful, but I would rather simply use parentheses so that anyone reading the code *knows* without a doubt that a function is being called and this is *not* a built-in construct.

By-Name Parameter:
Let us say you want to pass an expression to a function, that you don't want to be evaluated at call time but rather inside the body of the function. You can do something like following(basically take a empty param function value as argument)..
def myMethod(proc: () => Boolean)

and the client code would look like..
myMethod(() => 5>3)

Instead you can use By-name params which start with '=>'. Here is how it'll look then..
def myMethod(proc: => Boolean)

and the client code would look like..
myMethod(5>3)
Note that, the expression (5 <3) will not be executed unless myMethod uses proc somewhere inside the body.

Ch10- Composition and Inheritance
For abstract methods, one does not need to specify the "abstract" keyword as that in java

override keyword is mandatory if you're overriding a method from the parent class, its optional if you're implementing an abstract method of the parent class.

Scala has same namespace for instance variable and methods names unlike java. That is you can't have a field and a method with same identifier in scala AND a field(val) can override a parameterless method(def) with same name. However, viceversa is not true that is a parameterless method can't override a field with same name.

In general, scala's inheritence and composition is pretty similar to java's. But there are some striking differences in the syntax and it offers a bag of tricks to reduce code size.

One of the important things to learn from this chapter is the design it offers in the end for exposing the abstract Element via factory methods without exposing any of the concrete subtypes of Element as follow...

abstract class Element {
...
...
private class ArrayElement(x: Array[String]) extends Element { ..}
private class LineElement(s: String) extends Element { ... }
}
object Element {
def elem(x: Array[String]) = new ArrayElement(x)
def elem(x: String) = new LineElement(x)
}


Ch11- Scala's Hierarchy
AnyRef is just an alias for java.lang.Object. By default, all the scala classes inherit AnyRef and a marker trait called ScalaObject.

Instead of ==, In scala AnyRef has a method eq that is final and does the reference equality check. Opposite of eq is ne.

scala.Null is subclass of every reference(not value) class and scala.Nothing is subclasses of every class in scala.

Ch12- Traits
Traits are fundamental unit of code reuse in scala, They contain method and field definitions, which can then be reused by mixing them into classes. One class can mixin with any number of traits.

Traits are defined exactly like class except the keyword use is trait instead of class. It can be mixed in to a class using either the extends or with keywords. If you use extends then superclass of the trait is automatically inherited.

A trait defines a type also. So you can have var or val whose type is a trait's name.

Traits can't have any parameters in its constructor.

In traits, super calls are dynamically bound, while in normal classes its statically bound.

Two major use of traits are...
> turning a thin interface into a rich one (by providing implementation of some of the methods)
> use them as stackable modifications: see this post.

To trait, or not to:
If the behavior will not be reused, then make it a concrete class. If the behavior will be reused in multiple unrelated classes then make it a trait. Use abstract class instead if you want to inherit it from java code, since there is no analogue to traits in java.
And BTW, a trait with only abstract members translates directly into a java interface.

Ch13 - Packages and Imports
In Scala, access modifier can be augmented with qualifiers. A modifier of the form private[X] or protected[X] means that access is private or protected "up to" X, where X designates some enclosing package, class or singleton object.

Other interesting thing about imports in scala are that they can appear anywhere, can refer to objects and also naming the imports.. some examples of import definitions would like following...

import search._ //imports everything inside package search
import search.DepthFirstSearch //imports definition of DepthFirstSearch
import search.{DepthFirstSearch => DFS} //importing same as above, but can refer as DFS.. renamed the import

Ch15 - Case Classes
They're used to provide pattern matching(a very general one).

Scala compiler adds some convenience methods to a case class-
  • You can construct the instance without writing the new keyword.
  • All the paratemers defined in the primary class constructor automatically get the val prefix, so that they are visible as fields automatically.
  • The compiler adds "natural" implementaions of hashCode(), toString() and equals() to your class.

match in scala vs switch in java -
  • match is an expression(always returns a value)
  • alternative expressions never "fall through" into the next case, no need for break.
  • if none of the patterns match then it throws MatchError exception

Mostly all patterns look exactly like the corresponding expression.

Type of Patterns:
  • Wildcard pattern (_): matches anything
  • Constant pattern : matches constants to themselves
  • Variable pattern : a variable in the pattern matches to any object and scala binds the variable to the matched object
  • Scala treats all the identifiers starting with a capital letters as constant, same is really a constant expression and not a variable expression. If you want to use an identifies starting with a small letter as constant expression then you'll have to enclose it in backquotes.
  • Constructor pattern: Assuming A is a case class we can use the constructor expression of this class as a pattern.
  • Sequence patterns : You can match against scala sequences like List or Array
  • Tupple patterns : You can match against tuples too
  • Typed patterns: They can be used as a convenient replacement for the type tests, such as *case x:String => whatver* .. this is something similar to x.isInstanceOf[String]. (Note: to cast something into string you would write x.asInstanceOf[String], as you can see they're rather verbose and that is because scala discourages their use, you should better use typed pattern)
  • Scala uses the erasure model of generics just like java, that means no information about the type argument is maintained at runtime, that is with the pattern matching you can match an object for being Map but not Map[Int, Int].
  • Variable binding pattern: with this you can bind the result of a pattern match to a variable. For example, the pattern *UnOp("abs", e @ UnOp("abs", _))* matching will bind e to result of pattern appearing after @.

Pattern guards:
In general, scala patterns are linear that is you can't write same variable twice in a pattern, if you need such thing anywhere.. look up pattern guards :)
Patterns are tried in the order they are written.

Sealed Class:
If a class is sealed, then only classes defined in the same file can inherit it. This lets scala help you fulfil your intent of not letting someone else define another case class inheriting it.

Option:
The best way to get value apart from optional value(Some(value)) is by using a match expression. It recommeded to use Optional values instead of nulls in scala.

Patterns Everywhere:
Patterns are allowed in many more places and not just in match expression.
  • Whenever you define a val or var, you can use pattern instead of simple identifier.
  • A sequence of cases in curly braces can be used anywhere a function value can be used.
  • If you're using a sequence of cases as function literal and you don't want to exhaust all the cases then make it a PartialFunction. Partial functions have a method "isDefinedAt" that can tell whether its defined for a particular input or not. Partial functions are recommended not be used unless there is a real good reason to use them.
  • Patterns can be used in for expressions also.

Sunday, August 9, 2009

Programming In Scala: Chapter#6,7 notes

Ch6-
Fuctional objects = immutable objects, this chapter basically shows you how to write class for immutable Rational object. Many key concepts of writing classes in scala are covered.

In scala class, Two kind of constructors, primary and auxiliary. Its mandatory that an auxiliary constructor invokes anothe constructor.
Only primary constructor can invoke the constructor of superclass.

In scala class, Getters and setters are "generated" only for the field variables(unless they are declared private)

override keyword needs to be explicitly used when overriding a method of the superclass.

Though scala compiler allows you to use '$' in identifier name, but it *MUST NOT* be used as its reserved for identifiers generated by scala compiler and there may be clashes.

Conventionally, identifiers for constants in java are like X_OFFSET, but in scall its recommended to use only first letter capital for constants and same identifier in scala should be XOffset.

A literal identifier trick can be used if you want to use a reserved word as identifier. A literal identifier is an identifier enclosed in back quotes.

Method overloading is supported that is same method name can be used for two different methods as long as there is some difference in method signature.

There is an implicit conversion trick that allows you to convert any type into any other type. Its very powerful but highly recommended not to be used and hence I'm not even mentioning here how its done :)

Ch7-
if, while, do-while, for, try, match - all return some value

Scala assignment always returns the unit value, ().

It recommends to use recursion rather than while loops to achieve the same effect.

for loop is swiss army knife in scala(seems inspired from loop macro in lisp), it can be used to do many different iteration tasks. Please see section 7.3 for its usage.


Scala's exceptions behave like same in java, thrown using throw keyword.Catching exception syntax is different a little bit and seems to less the code needed in handling multiple exceptions.

If a method throws an exception, its not mandatory for it to declare it using the throws as in java.

finally keyword is also available whose behavior is exactly as that in java.

"Match" is "switch" of java. However switch allows only matching of integers and enums whereas "Match" lets you select using arbitrary patterns.

Saturday, August 8, 2009

Programming In Scala: Chapter#4,5 notes

Ch4-
public is scala's default access level.

Method parameters in scala are val, they can't be reassigned.

In the absence of any returned statement, scala returns the last expression value computed by the method. The recommeded or the functional way is not to have explicit return statements and to definitely avoid multiple return statements. This philosophy encourages you to make small methods that just do one thing and not many.

Braces around the method definition are optional if there is only one expression inside the method body.

If you have a method whose return type is Unit, you can write it like following(removing the = sign) so that it looks like a procedure and clarifies the intention that its there for side effects only..
def add(a:Int) {sum+=a}

One thing to notice here is that whenever you write a function in procedural style(that is without equal sign), its infered return type is definitely going to be Unit no matter what the body contains.
A semicolon is *must* if you write multiple statements on a single line.

The rules of semicolon inference:
1. The line in question ends in a word that would not be legal as the end of a statement, such as a period or as an infix operator.
2. The next line begins with a word that cannot start with a statement.
3. The line ends while inside parentheses(...) or brackets [...], because these cannot contain multiple statements anyway.

Sigleton Objects: Scala classes can't have static fields or method, instead there can be singleton object whose definition looks exactly like scala classes with class replaced with keyword object. If there is a class with same name then singleton object is called companion object of that class, similarly that class is called companion class of this singleton object. Companion class/object can access private members of each other. A singleton object and the companion class *MUST* be defined in the same source file.


Ch5-
Other than the value types(corresponding to every primitive type in java) such as Byte, Short, Int, Long, Float, Double and Boolean, scala has a type called symbol which is like scheme symbols and literal representation is same as scheme symbols, they start with single quote e.f.'symbol

Symbols are interned, if you write the same symbol twice, they both refer to the same symbol object.

unary_x, where x = +/-/!/~ can be used in prefix notation that is 2.unary_- is same as -2.

If a method takes no arguments, it can be written in postfix notation, that is s.toStrin() can be written as "s toString".

A == B in scala first checks to see if A is null, if its not then it checks
A.equals(B). In java '==' compares referential equality which here is done with method eq(this only applies to the objects which can be directly mapped into java objects)

Scala doesn't have operators, so how does 2+2*7 return 16. The answer is that precedence is based on the first letter of the method name and method starting with * have higher precedence than methods starting with +.

The associativity(when there are multiple methods with same precendence) is determined by the last character of the method name.

For every basic scala type, there is a rich wrapper that provides more utility methods on it.

Monday, August 3, 2009

Programming In Scala: Chapter#2,3 notes

I did a quick reading of above mentioned chapters from Programming in Scala by Martin Odersky and noted a few key things...

A scala compiler does not infer function parameter types, it does so only for the function return type.

If function is recursive, you must specify its return type.

If function body has only a single expression then you can optionally leave out the curly braces.

"Unit" type is returned from the functions that don't do anything useful, its like java void.

If a function literal consists of only one expression that takes the argument then we may skip writing the argument explicitly. Let me give an example..

array.forEach(arg => println(arg))

is equivalent to

array.forEach(println)
There are two kinds of variables in scala, var and val. val are final and can't be reassigned. Although the variables defined with val are final. but the object, they are refering to, might very well be mutable.

If a method takes only one parameter then you can call it without using the parenthesis. In reality there are no operators in scala(as in scheme:)) and the op looking variables are actually functions taking advantage of the mentioned fact. For example, "1 + 2" is actually "1.+(2)"
If a method is used in operator notation like a op b, then it means a.op(b) except in the case where method name ends with colon and then "a op: b" mean b.op:(a)

If you say greet("hi") on a variable, it automatically gets converted to greet.apply("hi") that is why array elements can be accessed with array(index) syntax. Similarly greet("hi")=value is transformed into greet.update("hi",value).

Pretty much for every data structure, scala provides both, mutable and immutable implementations.

Tuples can be used for multiple value return from a function.

semicolons are mostly optional.

Scala supports functional as well as imperative programming but encourages to use functional unless its justifiable to use the other one and hence prefer val over var, immutable object over mutable object and functions with no side effects over functions with side effects.