Thursday, December 10, 2009

Xml Transformation 1

Unlike most Java Xml Apis the Scala Object model consists of immutable object. This has two major consequences:
  • There is no reference to the parent node because that would cause the XML to be very expensive during transformations
  • Transforming the XML requires creating new nodes rather than changing the existing nodes

Both point cause non-functional programmers to feel a little uneasy but in practice only the first restriction causes any real discomfort.

Two methods for XML transformation will be demonstrated in this and the next topic.
  1. scala> val xml = <library>
  2.      | <videos>
  3.      | <video type="dvd">Seven</video>
  4.      | <video type="blue-ray">The fifth element</video>
  5.      | <video type="hardcover">Gardens of the moon</video>
  6.      | </videos>
  7.      | <books>
  8.      | <book type="softcover">Memories of Ice</book>
  9.      | </books>
  10.      | </library>
  11. xml: scala.xml.Elem = 
  12. <library>
  13.        <videos>
  14.        <video type="dvd">Seven</video>
  15.        <video type="blue-ray">The fifth element</video>
  16.        <video type="hardcover">Gardens of the moon</video>
  17.        </videos>
  18.        <books>
  19.        <book type="softcover">Memories of Ice</book>
  20.        </books>
  21.        </library>
  22. scala> import scala.xml._
  23. import scala.xml._
  24. scala> import scala.xml.transform._
  25. import scala.xml.transform._
  26. // Some of the books are labelled as videos
  27. // not books so lets select those elements
  28. scala> val mislabelledBooks = xml \\ "video" filter {e => (e \\ "@type").text == "hardcover"}
  29. mislabelledBooks: scala.xml.NodeSeq = <video type="hardcover">Gardens of the moon</video>
  30. // we can create a rule that will remove all the
  31. // selected elements
  32. scala> object RemoveMislabelledBooks extends RewriteRule {
  33.      | override def transform(n: Node): Seq[Node] ={ 
  34.      | if (mislabelledBooks contains n) Array[Node]()
  35.      | else n
  36.      | }
  37.      | }
  38. defined module RemoveMislabelledBooks
  39. // a quick test to make sure the elements are removed
  40. scala> new RuleTransformer(RemoveMislabelledBooks)(xml)
  41. res1: scala.xml.Node = 
  42. <library>
  43.        <videos>
  44.        <video type="dvd">Seven</video>
  45.        <video type="blue-ray">The fifth element</video>
  46.        
  47.        </videos>
  48.        <books>
  49.        <book type="softcover">Memories of Ice</book>
  50.        </books>
  51.        </library>
  52. // Now another rule to add them back
  53. scala> object AddToBooks extends RewriteRule {                             
  54.      | override def transform(n: Node): Seq[Node] = n match {                                
  55.      | case e:Elem if(e.label == "books") =>                                                 
  56.      |   val newBooks = mislabelledBooks map { case e:Elem => e.copy(label="book") }
  57.      |   e.copy(child = e.child ++ newBooks)                                                 
  58.      | case _ => n
  59.      | }
  60.      | }
  61. defined module AddToBooks
  62. // voila done
  63. scala> new RuleTransformer(RemoveMislabelledBooks, AddToBooks)(xml) 
  64. res4: scala.xml.Node = 
  65. <library>
  66.        <videos>
  67.        <video type="dvd">Seven</video>
  68.        <video type="blue-ray">The fifth element</video>
  69.        </videos>
  70.        <books>
  71.        <book type="softcover">Memories of Ice</book>
  72.        <book type="hardcover">Gardens of the moon</book></books>
  73.        </library>

Wednesday, December 9, 2009

Futures

Futures are mainly tokens returned by an actor that promises a result sometime in the future. The typical place one encounters a future is from an actor. The !! method of an actor returns a future. However in addition the Futures object provides several methods for doing parallel processing without having to write actors (or threads for that matter.)

Note: My use of scala.util.Random requires Scala 2.8 but I think the rest is 2.7.7.
  1. scala> import scala.actors.Futures._                
  2. import scala.actors.Futures._
  3. /* 
  4. The most basic future example.  
  5. Just runs the function in a seperate thread and returns a Future object
  6. for the result
  7. */
  8. scala> future {Thread.sleep(10000);println("hi");10}
  9. res2: scala.actors.Future[Int] = < function0>
  10. /* 
  11. Use one of the future methods for obtaining the actual result
  12. this one blocks tile ready, but other can check if result is ready and so on
  13. */
  14. scala> res2()
  15. hi
  16. res3: Int = 10
  17. /*
  18. This is more interesting. 
  19. The method creates several futures and the using the awaitAll method 
  20. waits for all the futures to complete before continuing
  21. */
  22. scala> def bubbles = {                                                                                                             
  23.      | val bubbles = for( i <- 1 to 20) yield {
  24.      |   future {
  25.      |     Thread.sleep(scala.util.Random.nextInt(20)*500)
  26.      |     println("pop "+i)
  27.      |     "pop "+i
  28.      |   }
  29.      | }
  30.      | awaitAll(30000, bubbles:_*) foreach println _                                                                               
  31.      | }
  32. bubbles: Unit
  33. scala> bubbles
  34. pop 9
  35. pop 12
  36. pop 11
  37. pop 5
  38. pop 3
  39. pop 14
  40. pop 20
  41. pop 10
  42. pop 1
  43. pop 4
  44. pop 16
  45. pop 6
  46. pop 7
  47. pop 2
  48. pop 8
  49. pop 18
  50. pop 15
  51. pop 19
  52. pop 17
  53. pop 13
  54. Some(pop 1)
  55. Some(pop 2)
  56. Some(pop 3)
  57. Some(pop 4)
  58. Some(pop 5)
  59. Some(pop 6)
  60. Some(pop 7)
  61. Some(pop 8)
  62. Some(pop 9)
  63. Some(pop 10)
  64. Some(pop 11)
  65. Some(pop 12)
  66. Some(pop 13)
  67. Some(pop 14)
  68. Some(pop 15)
  69. Some(pop 16)
  70. Some(pop 17)
  71. Some(pop 18)
  72. Some(pop 19)
  73. Some(pop 20)
  74. scala> import java.net._                                                                                        
  75. import java.net._
  76. scala> import scala.io._
  77. import scala.io._
  78. /*
  79. A kind of funny example.  We set off two futures to download the google page
  80. and print the first that finishes
  81. */
  82. scala> def load = {
  83.      | val com = future {
  84.      |   val comStream = new URL("http://www.google.com").openStream()                                                                       
  85.      |   Source.fromInputStream(comStream).getLines().mkString("\n")
  86.      | }
  87.      | val ch = future {
  88.      |   val chStream = new URL("http://www.google.ch").openStream()
  89.      |   Source.fromInputStream(chStream).getLines().mkString("\n")
  90.      | }  
  91.      | awaitEither(ch,com)                                                                                               
  92.      | }
  93. load: Any
  94. scala> load
  95. res0: Any = 
  96. & !doctype html...

Tuesday, December 8, 2009

Labelled Multiple Returns

A cool idea I found at http://stackoverflow.com/questions/1827672/is-there-a-way-to-have-tuples-with-named-fields-in-scala-similar-to-anonymous-cl. A very simple idea but very useful.
To summarize, you want to return multiple values but want to assign names to the values rather than use a tuple which more or less assigns indices to the different values. Here are a couple of solutions:

Using structured types. Simplest solution with the least extra code.
  1. scala> def multipleReturns1 = {
  2.      | new { val first = 1; val second = 2 }
  3.      | }
  4. multipleReturns1: java.lang.Object{def first: Intdef second: Int}
  5. scala> multipleReturns1
  6. res0: java.lang.Object{def first: Intdef second: Int} = $anon$1@549b6976
  7. scala> res0.first
  8. res1: Int = 1
  9. scala> res0.second
  10. res2: Int = 2
  11. scala> import res0._
  12. import res0._
  13. scala> first
  14. res3: Int = 1
  15. scala> second
  16. res4: Int = 2

Using case classes. Returns a product which has properties that may be useful.
  1. scala> def moreReturns = {
  2.      | case class Returns (one:Int, two:Int)
  3.      | Returns(1,2)
  4.      | }
  5. moreReturns: java.lang.Object with ScalaObject with Product{def one: Intdef two: Int}
  6. scala> moreReturns
  7. res5: java.lang.Object with ScalaObject with Product{def one: Intdef two: Int} = Returns(1,2)
  8. scala> res5.one
  9. res6: Int = 1
  10. scala> res5.two
  11. res7: Int = 2
  12. scala> import res5._
  13. import res5._
  14. scala> one
  15. res8: Int = 1
  16. scala> two
  17. res9: Int = 2
  18. scala> res5.productIterator foreach println _
  19. 1
  20. 2
  21. scala> res5.productPrefix
  22. res15: java.lang.String = Returns

Monday, December 7, 2009

Scala cheat sheet

One can never go wrong with a Cheat sheet. It is not all there but it is a nice start and well worth looking through.

http://anyall.org/scalacheat/

Scala 2.8 Traversable and IndexedSequence

This topic is really just a collection of examples using the Scala 2.8 API. The examples are mostly based on Strings. But because Strings are in fact an IndexedSeq all of these examples also work with Lists arrays and the first several work with all collections.

These examples are all based on first Traversable. The basis of all collections and therefore will work with all collections. And the next set of examples work with IndexedSeq and most will work with Seq as well. Sets, Maps and others still need to be examined.

This is not an exhaustive set of examples and not all are even that interesting (sorry :-) ). But I let out the most trivial unless theay are being compared to others.

Traversable:
  1. scala> val license = """Subject of Agreement. ?Product?, as referred to in this Agreement, shall be the binary software package ?Sun VirtualBox,? which Product allows for creating multiple virtual computers, each with different operating systems (?Guest Computers?), on a physical computer with a specific operating system (?Host Computer?), to allow for installing and executing these Guest Computers simultaneously. The Product consists of executable files in machine code for the Solaris, Windows, Linux, and Mac?OS?X operating systems as well as other data files as required by the executable files at run-time and documentation in electronic form. The Product includes all documentation and updates provided to You by Sun under this Agreement and the terms of this Agreement will apply to all such documentation and updates unless a different license is provided with an update or documentation."""
  2. res0: RandomAccessSeq[Char] = 
  3. license: java.lang.String = ...
  4. scala> license count (_ == 'u')
  5. res1: Int = 37
  6. scala> license split ' ' count {_ == "and"
  7. res3: Int = 6
  8. scala> license ++ " this is silly!"
  9. res0: RandomAccessSeq[Char] = ...
  10. scala> license dropWhile { _ != 'y'} drop 1 takeWhile { _ != 'y'}
  11. res6: Seq[Char] = RandomAccessSeqTW( , s, o, ...
  12. scala> license forall {_ != 'z'}
  13. res8: Boolean = true
  14. scala> (1 until 5).init
  15. res0: scala.collection.immutable.Range = Range(1, 2, 3)
  16. scala> (1 until 5).head
  17. res1: Int = 1
  18. scala> (1 until 5).tail
  19. res2: scala.collection.immutable.IndexedSeq[Int] = Range(2, 3, 4)
  20. scala> (1 until 5).last
  21. res3: Int = 4
  22. scala> (1 until 5).headOption
  23. res4: Option[Int] = Some(1)
  24. scala> (1 until 5).lastOption
  25. res6: Option[Int] = Some(4)
  26. scala> license max   
  27. res8: Char = y
  28. scala> license min
  29. res9: Char =  
  30. scala> List() nonEmpty 
  31. res10: Boolean = false
  32. scala> List() isEmpty 
  33. res11: Boolean = true
  34. scala> license partialMap {case c if ('a' to 'z' contains c) => c}
  35. res13: scala.collection.immutable.IndexedSeq[Any] = IndexedSeq(u, b, j, e, c ...)
  36. scala> 1 to 10000 by 2 product 
  37. res19: Int = 481029393
  38. scala> 1 to 10000 by 2 sum                   
  39. res23: Int = 25000000
  40. scala> license partition {"aeiou" contains _}
  41. res20: (StringString) = (ueoeeeouaeeeoiieeeaeeia ....
  42. scala> license span {_ != 'a'}
  43. res22: (StringString) = (Subject of Agreement. ?Product?, ,as referred to in this Agreement, shall be the binary software package ?Sun VirtualBox,? which Product allows for creating multiple virtual computers, each with differ ...
  44. scala> val consonants = license withFilter {c => !("aeiuo" contains c)}
  45. consonants: scala.collection.immutable.StringOps#WithFilter = scala.collection.TraversableLike$WithFilter@78e8a591
  46. scala> consonants foreach print _                                      
  47. Sbjct f Agrmnt. ?Prdct?, s rfrrd t n ths Agrmnt, shll b th bnry sftwr pckg ?Sn VrtlBx,? whch Prdct llws fr crtng mltpl vrtl cmptrs, ch wth dffrnt prtng systms (?Gst Cmptrs?), n  physcl cmptr wth  spcfc prtng systm (?Hst Cmptr?), t llw fr nstllng nd xctng ths Gst Cmptrs smltnsly. Th Prdct cnssts f xctbl fls n mchn cd fr th Slrs, Wndws, Lnx, nd Mc?OS?X prtng systms s wll s thr dt fls s rqrd by th xctbl fls t rn-tm nd dcmnttn n lctrnc frm. Th Prdct nclds ll dcmnttn nd pdts prvdd t Y by Sn ndr ths Agrmnt nd th trms f ths Agrmnt wll pply t ll sch dcmnttn nd pdts nlss  dffrnt lcns s prvdd wth n pdt r dcmnttn.


IndexedSequense additions to Traversable:
  1. scala> '!' +: license    
  2. res33: String = !Subject of Agreement
  3. scala> "hello" +: license
  4. res32: scala.collection.immutable.IndexedSeq[Any] = IndexedSeq(hello, S, u, b, j, e, c, t,  , o, f,  , A, g, r, e, e, m, e, n, t, .,  , ?, P, r, o, d, u, c, t, ?, ,,  , a, s,  , r, e, f, e, r, r, e, d,  , t, o,  , i, n,  , t, h, i, s,  , A, g, r, e, e, m, e, n, t, ,,  , s, h, a, l, l,  , b, e,  , t, h, e,  , b, i, n, a, r, y,  , s, o, f, t, w, a, r, e,  , p, a, c, k, a, g, e,  , ?, S, u, n,  , V, i, r, t, u, a, l, B, o, x, ,, ?,  , w, h, i, c, h,  , P, r, o, d, u, c, t,  , a, l, l
  5. scala> license(11)
  6. res35: Char = A
  7. scala> license diff ("aeiou")
  8. res47: String = Sbjct f Agreement. ?Product?, s referred to n this Agreement, shall be the binary software package ?Sun VirtualBox,? which Product allows for creating multiple virtual computers, each with different operating systems (?Guest Computers?), on a physical computer with a specific operating system (?Host Computer?), to allow for installing and executing these Guest Computers simultaneously. The Product consists of executable files in machine code for the Solaris, Windows, Linux, and Mac?OS?X operating systems as well as other data files as required by the executable files at run-time and documentation in electronic form. The Product includes all documentation and updates provided to You by Sun under this Agreement and the terms of this Agreement will apply to all such documentation and updates unless a different license is provided with an update or documentation.
  9. scala> license dropRight(30)
  10. res48: String = Subject of Agreement. ?Product?, as referred to in this Agreement, shall be the binary software package ?Sun VirtualBox,? which Product allows for creating multiple virtual computers, each with different operating systems (?Guest Computers?), on a physical computer with a specific operating system (?Host Computer?), to allow for installing and executing these Guest Computers simultaneously. The Product consists of executable files in machine code for the Solaris, Windows, Linux, and Mac?OS?X operating systems as well as other data files as required by the executable files at run-time and documentation in electronic form. The Product includes all documentation and updates provided to You by Sun under this Agreement and the terms of this Agreement will apply to all such documentation and updates unless a different license is provided wi
  11. scala> license takeRight(10)
  12. res49: String = mentation.
  13. scala> license indexWhere { "aeiou" contains _} 
  14. res4: Int = 1
  15. scala> license lastIndexWhere { "aeiou" contains _}
  16. res6: Int = 873
  17. scala> List(1,2,3) flatten {0 to _}
  18. res7: List[Int] = List(0, 1, 0, 1, 2, 0, 1, 2, 3)
  19. scala> ' ' +: license zip license indexWhere {case (last, c) => "" + last + c == "an"}       
  20. res14: Int = 343
  21. scala> license indexOfSlice ("and")
  22. res17: Int = 342
  23. scala> ('a' to 'z') ++ ('A' to 'Z'
  24. res25: scala.collection.IndexedSeqView[Char,IndexedSeq[_]] = IndexedSeqViewA(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)
  25. scala> license intersect res25
  26. res26: String = SubjectofAgrmnPdasihlywpkVBxvGCHTWLMOXqY
  27. scala> license diff res25     
  28. res27: String =   eeet. ?rouct?,  referred to n tis Agreement, shal be the binar softare acage ?Sun irtualo,? which Product allows for creating multiple irtual computers, each with different operating systems (?uest omputers?), on a physical computer with a specific operating system (?ost Computer?), to allow for installing and executing these Guest Computers simultaneously. he Product consists of executable files in machine code for the Solaris, indows, inux, and ac?S? operating systems as well as other data files as reuired by the executable files at run-time and documentation in electronic form. The Product includes all documentation and updates provided to ou by Sun under this Agreement and the terms of this Agreement will apply to all such documentation and updates unless a different license is provided with an update or documentation.
  29. scala> license filter res25
  30. < console>:7: error: type mismatch;
  31.  found   : scala.collection.IndexedSeqView[Char,IndexedSeq[_]]
  32.  required: (Char) => Boolean
  33.        license filter res25
  34.                       ^
  35. scala> license filter {res25 contains _}
  36. res29: String = SubjectofAgreementProductasreferredtointhisAgreementshallbethebinarysoftwarepackageSunVirtualBoxwhichProductallowsforcreatingmultiplevirtualcomputerseachwithdifferentoperatingsystemsGuestComputersonaphysicalcomputerwithaspecificoperatingsystemHostComputertoallowforinstallingandexecutingtheseGuestComputerssimultaneouslyTheProductconsistsofexecutablefilesinmachinecodefortheSolarisWindowsLinuxandMacOSXoperatingsystemsaswellasotherdatafilesasrequiredbytheexecutablefilesatruntimeanddocumentationinelectronicformTheProductincludesalldocumentationandupdatesprovidedtoYoubySununderthisAgreementandthetermsofthisAgreementwillapplytoallsuchdocumentationandupdatesunlessadifferentlicenseisprovidedwithanupdateordocumentation
  37. scala> license filterNot {res25 contains _}
  38. res30: String =   . ??,      ,       ? ,?        ,      (? ?),          (? ?),          .            , , ,  ??                -     .                                        .
  39. scala> license removeDuplicates
  40. res31: String = Subject ofAgrmn.?Pd,asihlywpkVBxv(GC)HTWLMOXq-Y
  41. scala> license segmentLength ({_ > 'A'},2) 
  42. res37: Int = 5
  43. scala> license drop 2 span {_ > 'A'} _1
  44. res41: String = bject
  45. scala> license sortWith Ordering.Char          
  46. res45: String =                                                                                                                                   (()),,,,,,,,,-....??????????AAAABCCCGGHLMOPPPPSSSSSTTVWXYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeefffffffffffffffffggggggggggghhhhhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiijkllllllllllllllllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooooooooooooooooooooooooooooooooooooooooopppppppppppppppppppqrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrsssssssssssssssssssssssssssssssssssssssssssssssttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvwwwwwwwwwwxxxxxyyyyyyyyy
  47. scala> 'a' to 'z' union ('A' to 'Z')
  48. scala> "hello world" patch (6, "goof", 5)
  49. res51: String = hello goof
  50. scala> "hello world" updated(0,'H')
  51. res54: String = Hello world

Friday, December 4, 2009

Yet more instances of '_'

A few more placeholder instances that I have remembered or was reminded of.
  1. scala> class MyClass {             
  2.      | var a:Int = _    // 1
  3.      | def countDown = 10 to 5 by -1
  4.      | }
  5. defined class MyClass
  6. scala> val obj = new MyClass()
  7. obj: MyClass = MyClass@6ff0239
  8. scala> val countDownMethod = obj.countDown _  // 2
  9. countDownMethod: () => Range = < function>
  10. scala> def multiple(a:Int)(b:Int) = a*b
  11. multiple: (Int)(Int)Int
  12. scala> val triple = multiple(3) _ // 3
  13. triple: (Int) => Int = < function>
  14. scala> List(1,2,3) foreach { _ => Console.println("Hello") } // 4
  15. Hello
  16. Hello
  17. Hello

  1. initialize a variable to its default value. If the = _ is left out then the definition will be an abstract declaration and will have to be defined in subclasses
  2. create a reference to the method (rather than invoking the method and having a reference to the resulting value) (Thanks Daniel)
  3. This is an example of currying; a new function is created with a single parameter.
  4. where the underscore is used as an ignored and unnamed parameter (Thanks Alex)

Wednesday, December 2, 2009

What the @*!% is with the '_'

  1. scala> import java.io._ // 1
  2. import java.io._
  3. scala> import java.io.{ File => _ } // 2
  4. import java.io.{File=>_}
  5. scala> object MyObj{ def count=(1 to 10) }
  6. defined module MyObj
  7. scala> import MyObj._ // 3
  8. import MyObj._
  9. scala> class MyClass { def countDown= 10 to 5 by -1} 
  10. defined class MyClass
  11. scala> val instance = new MyClass()
  12. instance: MyClass = MyClass@69ebcd0
  13. scala> import instance._ // 4
  14. import instance._
  15. scala> def multiply(by:Int,x:Int)=2*x
  16. multiply: (Int,Int)Int
  17. scala> val double=multiply(2, _:Int// 5 
  18. double: (Int) => Int 
  19. scala> count foreach {i => double(i)}
  20. scala> val double2:Int=>Int = multiply(2,_)
  21. double2: (Int) => Int = & function>
  22. scala> count foreach {i => double2(i)}
  23. scala> count reduceLeft {_+_} // 6
  24. res3: Int = 55
  25. class Generic[T](val t:T)
  26. val generic:Generic[_] = new Generic(2) // 7

While at a glance the underscores do not seem related, in fact the general rule is fill in the blank. Sca_la what goes in the blank?

Going through the examples:
  1. import anything/everything in package
  2. this seems to be an exception. Assign File to oblivion. (It is no longer imported)
  3. import all methods in object
  4. same thing. Import all methods in instance object
  5. creat a new method where the first parameter is defined but all others will be defined later. In this case a special syntax is required so the compiler knows that a new method is desired and the missing parameters was not simply a mistake. There is another syntax for defining methods that do not require the _ for currying
  6. reduceLeft takes method with 2 parameters. _ + _ creates a function of 2 parameters: the first '_' represents the first parameter and the second '_' represents the second parameter.
  7. the '_' represents any value. This syntax is frowned upon since Scala has such a rich type system but can be useful when interoperating with Java. Perhaps a better declaration would be Generic[Any]