Monday, 26 September 2011

Thursday, 2 June 2011

Monday, 28 February 2011

Clojure

In collaboration with Mr Yannick Malins as a result of having too much time in the evenings of a ski holiday. Not actual Scala but close enough.

Recurses thru a directory looking for 'test.txt' files and cats the result to the output file and stdout.


(import
'(java.io File FileWriter BufferedReader FileReader))

(def myfile (new File "C:\temp\source\"))
(def myfile2 (new File "C:\temp\out.txt"))

(defn recurse-files [file]
(if (.isDirectory file)
(apply str (map recurse-files (.listFiles file)))
(when (= (.getName file) "test.txt")
(let [reader (new BufferedReader (new FileReader file))]
(apply str (map
#(str (.getParent file) "/" % \newline)
(line-seq reader)))))))

(doto (new FileWriter myfile2)
(.write (recurse-files myfile))
(.close))

(recurse-files myfile)

Wednesday, 7 July 2010

Scala + Lift tutorial

If I go back to Scala heres a nice Lift tutorial link:

http://blog.m1key.me/2010/07/rest-with-scalas-lift-framework-part-1.html

Saturday, 11 July 2009

Implicits (base converter)

Defining a method as 'implicit' means that it becomes global to that package. Use with extreme care!!

Here is an integer base converter which I wrote:
Note how we can now call methods on the integers themselves

object Types {
case class NumberConverter(val i : Int) {
def octal = BaseBuilder(i, 8)
def hex = BaseBuilder(i, 16)
def mybase(base : Int) = BaseBuilder(i, base)
}

def BaseBuilder(i : Int, base : Int) : String = {
i match {
case 0 => ""
case _ => BaseBuilder(i/base, base) + baseToCharacter(i % base)
}
}

def baseToCharacter(i : Int) : String = {
return "" + {
if ( (0 to 9).contains(i) ) {
i
} else {
(i + 55).toChar
}
}
}

implicit def baseConverter(i : Int) : NumberConverter = NumberConverter(i)

def main(args : Array[String]) : Unit = {
println( 29 )
println( 29.hex )
println( 29.octal )
println( 15.mybase(16) )
println( 129.mybase(2) )
}
}

Sunday, 5 July 2009

Actors & Concurrency

Actors are the first thing I've found where Scala definently kicks Java's ass.

We dont use 'Synchronized' anymore. Instead each 'Actor' has a sort of 'mail box' or 'to do list' that other processes can call either Synchronously or Asynchronously.

code:


package scalaexperiment

import scala.actors._
import Actor._

case class SayHi
case class SayThis(s : String)
case class GetActorStatus

object Actors {
def main(args : Array[String]) : Unit = {
val man = new Man1

(0 to 3).foreach( a => {
man ! SayHi //Asynchronous calls
man ! SayThis("gobblydgook "+a)
man ! Actors
})

println("I am going to wait here...")
val count = man !? GetActorStatus //Sychronous call
println("....For you to tell me how many times you were called: "+count)
}
}

class Man1 extends Actor {
val s = "From Actor> "
var count = 0;
def act = loop {
react {
count += 1
doOptions
}
}

def doOptions : PartialFunction[Any, Unit] = {
case GetActorStatus => reply(count)
case SayHi => println(s+"hi")
case SayThis(a) => println(s + a)
case _ => println(s+"Dont know what you asked me to say ")
}
this.start
}


Tip: Dont forget to call 'start' on your Actors.

Additional:
! = Asynch call
!? = Synch call (wait for me!)
!! = Asynch call that returns a Future[T] value
reactWithin(n) = react within n milliseconds.
!?(n, param) = wait n seconds for result.

Thursday, 2 July 2009

More Partial Functions

Here I am defining a couple of PartialFunctions and using them:

def main(args :Array[String]) :Unit = {

def f1 : PartialFunction[List[String], String] = {
case "a" :: rest => "I got an A"
}
def f2 : PartialFunction[List[String], String] = {
case "a" :: "b" :: rest => "I got an A and the next letter is a B"
}
def f3 = f2 orElse f1

println( handleRequest2( "a"::"c"::"a"::"b"::Nil)(f3) )
}

def handleRequest2(req : List[String])
(exceptions : PartialFunction[List[String], String]) : String = {
if (req.isEmpty) {
""
} else if (exceptions.isDefinedAt(req)) {
exceptions(req) + "\n" + handleRequest2( req.tail )(exceptions)
} else {
"Normal handle "+req.head+" ..done" + "\n" + handleRequest2( req.tail(exceptions)
}
}


Output [is unsurprisingly]:

I got an A
Normal handle c ..done
I got an A and the next letter is a B
Normal handle b ..done

Saturday, 20 June 2009

Functions passed to functions (delegates)


def turnNumbersToEven() = {
val nums = 1 to 20
println( nums.map(a => addOneToNumberIf(a % 2 == 1)( a)) )
}
def addOneToNumberIf( test : => Boolean)( i : Int) : Int = {
if (test) {
return i + 1
} else {
return i
}
}


Note because we used addOneToNumberIf(a)(b) notation instead of addOneToNumberIf(a,b) notation we are allowed to write scripts {} like this:


def turnNumbersToEven() = {
val nums = 1 to 20
println( nums.map(a => addOneToNumberIf {a % 2 == 1} (a)) )
}

Wednesday, 17 June 2009

You can use loops instead of compex maps

For example:

Using this 'for' loop the 'yield' function acts like a flatmap:

def loopMe() = {
val numbers = for( i <- 1 to 10; if i % 2 == 0;
j <- i to 10 if j % 2 == 1) yield i * j
println(numbers)
}


Here is the equivalent with traditional maps and filters:

def mapMe() = {
val num2 = (1 to 10).filter( a => a % 2 == 0)
val num3 = num2.flatMap( a => (a to 10).filter(b => b % 2 == 1).map(c => c * a ) )

println(num3)
}

Option[T]

Option[T] can be either a Some[T] or None

use this for things that can flatmap!

Xml demos

Basic XML with scala:
Note you can also use the CDATA command but blogger didn't like me having that here!

def xmlDemo() : Unit = {
val xml = <>my xml
<>1< /val >
<>2< /val >
< /b >
println( xml.length )
}


Filtering XML:
loads XML,
finds how many 'para' tags are in the XML
prints all the 'id' attributes of the 'sect2' tag
Note: \\ means find anywhere \ means find one level down

val xml3 = XML.load("http://www.linux.sgi.com/LDP/authors/template/Sample-HOWTO.xml")
println( (xml3 \\ "para").length )
println( (xml3 \\ "sect2").map(_ \ "@id").map(_.text) )


Transforming XML:

find any nodes which have an 'id=copyright' attribute and remove them

val moveIt = new RewriteRule {
override def transform(n : Node) : NodeSeq = n match {
case e:Elem if (e \"@id").text == "copyright" => NodeSeq.Empty
case e => e
}
}
println( new RuleTransformer(moveIt).transform(xml3) )

Sunday, 14 June 2009

String parsing thru lists

Filter numbers from strings.

println( "there are 7 numbers 8 in 2 here"
.toList.filter(Character.isDigit) )


Load the first word only.

println(("first word only".toList.takeWhile(c => c != ' ') ).mkString)

Funky stuff with for loops & prepopulating lists

You can pre populate a list with a loop like "val list = 1 to 20"

You can return stuff from a for loop with the "yield" command

def looping() = {
val myList = (1 to 20 by 3)
println(myList)

val list2 = for( i <- myList if i % 2 == 0 ) yield i
println(list2)
}

Functions apply and update

If you have an object with an 'apply' method you dont need to specify apply when calling it. ie: a.apply(20) === a(20)

Similar behavior with 'update' except you can use an '='. I'm currently baffled as to why you'd want to do this: a.update(6, "str") === a(6) = "str"


object Functions {

def main(args :Array[String]) = {
val a = new Ap(6)
println( a.apply(20) + " == " + a(20))
println( a.update(6, "str") + " == " + (a(6) = "str") )
}

}

class Ap(i : Int) {
def apply(in : Int) = (in + i).toString
def update(in : Int, v : String) = println("hey "+in+" "+v)
}

Passing Functions to functions

Obviously unlike java 'basic' is not executed until in the function 'answer'.


object Functions {

def main(args :Array[String]) = {
println("rec: " + answer( basic ))
}

def basic(i : Int) : String = i.toString

def answer( f : Int => String ) = f.apply(42)
}

cool list functions

list functions:

list.zipWithIndex = (a,b,c) => (a=>1,b=>2,c=>3)
list.slice(start,end) = cuts out this part of the list
list.take(n) ::: list.drop(n) == list = get the first n elements append them to not the first n elements

Friday, 12 June 2009

Functions inside functions

Methods inside methods can reference the variables in the outer methods. Check this:
Note the 'n's:


def drop[T](N: Int, l: List[T]): List[T] = {
def dropR(c: Int, curList: List[T]): List[T] = (c, curList) match {
case (_, Nil) => Nil
case (1, _ :: tail) => dropR(N, tail)
case (_, e :: tail) => e :: dropR(c - 1, tail)
}
dropR(N, l)
}


The above is a Method to remove every 'N'th element in the list.
Note the way they stick the counter on to the head of the list in the case statement.

This is how I did it - a completely different solution. [Is this Java-ery or funky and functional - I'm not sure].

list.zipWithIndex.partition( a => a._2 % count == count-1 )._2.map( a => a._1)

Wednesday, 3 June 2009

tuples

val a = (4,"fish")

//to retrieve values do this:
a._1
a._2

Dont think loop!

When ever you want to loop thru a list returning a new list of values use map or flatmap

If you do need to loop:
for( i <- 0 until 4) {
}

Thursday, 28 May 2009

Comparable anonymous types

Defining a function that takes an Anonymous type that can be compared.

Here we have 't' of type 'U' that can be '<' or '>'

def addValue[U > : T < % Ordered[U]](t: U) =