Saturday, December 26, 2009

Product

As a response to a comment on a previous post about about Tuples this topic is about Products and the most common subclasses of Tuples.

I should preface this post by saying that I am not going to attempt any scholastic style discussions, instead I am going to try to explain Product in practical terms and stay away from theory. That said on can think of Products as (potentially) heterogenous collections (non-resizable collections). There are several Product classes (Product, Product1, Product2...). All Product classes extend Product, which contains the common methods. Product has the methods for accessing the Product members and the subclass adds type information about the Members.

A good way to think about Product is to look at Tuple which is a Product. There is a good stack overflow question that is worth looking at.

To give more context consider other well known subclasses of Product:
  • All case classes
  • List
  • Option

  1. scala> val product : Product = (1,'2',3)
  2. product: Product = (1,2,3)
  3. scala> product.productIterator.foreach {println _}
  4. 1
  5. 2
  6. 3
  7. scala> product.productArity                       
  8. res1: Int = 3
  9. scala> product.productElement(2)
  10. res2: Any = 3
  11. scala> product.productPrefix    
  12. res3: java.lang.String = Tuple3
  13. scala> product.toString
  14. res4: java.lang.String = (1,2,3)
  15. scala> val product3 = product.asInstanceOf[Product3[Int,Char,Int]]
  16. product3: Product3[Int,Char,Int] = (1,2,3)
  17. scala> product3._2
  18. res5: Char = 2
  19. scala> product3._3
  20. res6: Int = 3
  21. scala> case class Test(name:String, passed:Boolean, error:String)
  22. defined class Test
  23. scala> Test("Chicken Little"false"the sky is falling")
  24. res7: Test = Test(Chicken Little,false,the sky is falling)
  25. scala> res7.productArity
  26. res8: Int = 3
  27. scala> res7.productIterator mkString ", "   
  28. res9: String = Chicken Little, false, the sky is falling

Friday, December 18, 2009

Tuples are (not?) Collections

Tuples are quite handy but a potential annoyance is that at a glance they seem list-like but appearances can be deceiving. The normal collection methods are not supported by Tuples. For example suppose you like the simple syntax: (1,2,3) better than List(1,2,3). With the Tuple you cannot do the maps, filters, etc... (with good reason) but there is a use-case for being able to convert a Tuple to a Traversable.

Word of warning. Unlike collections Tuples are very often not homogeneous. IE you do not have Tuple2[Int] you have Tuple2[A,B]. So the best you can do is to map a tuple to an Iterator[Any].

Note: this was done with Scala 2.8 so results may be slightly different with 2.7. But I believe the syntax is valid.
  1. // the productIterator method gives access to an iterator over the elements
  2. scala> (1,2,3).productIterator.map {_.toString} mkString (",")
  3. res1: String = 1,2,3
  4. scala> (1,2,3).productIterator foreach {println _}            
  5. 1
  6. 2
  7. 3
  8. // if you know the tuple is heterogeneous then you can use partial functions
  9. // for casting the elements to a particular type.  
  10. scala> (1,2,3).productIterator map {case i:Int => i + 2} foreach {println _}
  11. 3
  12. 4
  13. 5
  14. // To get a full Traversable out of the deal you use one of the many
  15. // to* methods to convert to Seq, List, Array, etc...
  16. scala> (1,2,3).productIterator.toList map {case i:Int => i + 2}      
  17. res15: List[Int] = List(3, 4, 5)
  18. // and if you want you can use an implicit to clean up the syntax a bit
  19. // Problem with this is you need an implicit for each Tuple length
  20. scala> implicit def tupleToTraversable[T](t:(T,T,T)) = t.productIterator.toList map { case e:T => e}
  21. warning: there were unchecked warnings; re-run with -unchecked for details
  22. tupleToTraversable: [T](t: (T, T, T))List[T]
  23. scala> (1,2,3) foreach {println _}
  24. 1
  25. 2
  26. 3
  27. /* 
  28. EDIT:  Dan pointed out that the methods I am using are inherited from the
  29. Product super class of Tuple.  So you can do something similar as follows.
  30. Note:  I am using the same name as the previous method so that they don't interfer 
  31. with one another
  32. */
  33. scala> implicit def tupleToTraversable[T](t:Product) = t.productIterator.toList map { case e:T => e} 
  34. warning: there were unchecked warnings; re-run with -unchecked for details
  35. tupleToTraversable: [T](t: Product)List[T]
  36. scala> (1,2,3) foreach {println _}
  37. 1
  38. 2
  39. 3
  40. // this is interesting... it does cast to int unless required
  41. scala> (1,2,'t') foreach {println _}
  42. 1
  43. 2
  44. t
  45. // lets verify we are getting correct conversion
  46. scala> def inc(l:List[Int]) = l map {_ + 1} 
  47. inc: (l: List[Int])List[Int]
  48. scala> inc ( (1,2,3))                              
  49. res4: List[Int] = List(2, 3, 4)
  50. // yep this I expected
  51. scala> inc ( (1,2,'t'))
  52. java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Integer
  53. at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source)
  54. at $anonfun$inc$1.apply(< console>:7)
  55. at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:238)
  56. at .< clinit>(< console>)
  57. scala> def inc(l:List[Int]) = l foreach {println _}
  58. inc: (l: List[Int])Unit
  59. scala> def p(l:List[Int]) = l foreach {println _}  
  60. p: (l: List[Int])Unit
  61. scala> p ( (1,2,'t'))                              
  62. 1
  63. 2
  64. t

Wednesday, December 16, 2009

Specs BDD Testing framework

This is the second Scala test framework topic and focuses on the excellent Specs framework. The other topic was on ScalaTest, another excellent testing framework for Scala.

Specs is focussed on BDD testing (Behaviour Driven Design) and is the inspiration for ScalaTests WordSpec. From what I understand Specs was in-turn inspired by RSpec the Ruby BDD testing framework.

Specs has some truly unique features to it which we will encounter in future topics. But for now just the basics. The following example tests a couple of Scala's XML support in order to demonstract the general pattern followed when writing Specs' tests.

  1. # scala -classpath ~/.m2/repository/org/scala-tools/testing/specs/1.6.1/specs-1.6.1.jar
  2. scala> import org.specs._
  3. import org.specs._
  4. scala> object XmlSpec extends Specification {
  5.      |  val sample = <library>
  6.      |         <videos>
  7.      |         <video type="dvd">Seven</video>
  8.      |         <video type="blue-ray">The fifth element</video>
  9.      |         <video type="hardcover">Gardens of the moon</video>
  10.      |         </videos>
  11.      |         <books>
  12.      |         <book type="softcover">Memories of Ice</book>
  13.      |         </books>
  14.      |         </library>
  15.      |  "Scala XML" should {
  16.      |   "allow xpath-like selection" in {
  17.      |    (sample \\ "video").size must be (3)    
  18.      |   }
  19.      |   "select child nodes" in {
  20.      |    // This test fails because child is a sequence not a string
  21.      |    // See the results of the tests
  22.      |    sample.child must contain (<videos/>)
  23.      |   }
  24.      |  }
  25.      |  }
  26. defined module XmlSpec
  27. scala> XmlSpec.main(Array[String]())
  28. Specification "XmlSpec"
  29.   Scala XML should
  30.   + allow xpath-like selection
  31.   x select child nodes <-- x indicates failure.
  32.     'ArrayBuffer(
  33.                    , <videos>
  34.                    <video type="dvd">Seven</video>
  35.                    <video type="blue-ray">The fifth element</video>
  36.                    <video type="hardcover">Gardens of the moon</video>
  37.                    </videos>, 
  38.                    , <books>
  39.                    <book type="softcover">Memories of Ice</book>
  40.                    </books>, 
  41.                    )' doesn't contain '<videos></videos>' (< console>:24)
  42. Total for specification "XmlSpec":
  43. Finished in 0 second, 52 ms
  44. 2 examples, 2 expectations, 1 failure, 0 error

By-name-parameter to Function

Today's topic is related to Defining Custom Control Structures. By name parameters are not function objects in the same way as other functions. Normally you need to invoke a function:
  1. scala> def exec(func: () => Int) = func()
  2. exec: (() => Int)Int
  3. // exec invokes the function so 10 is the result
  4. scala> exec (() => 10)  
  5. res1: Int = 10
  6. scala> def exec(func: () => Int) = func
  7. exec: (() => Int)() => Int
  8. // here exec returns the function:
  9. scala> exec (() => 10)                 
  10. res2: () => Int = <function>

Compare that to a by-name-parameter function:
  1. scala> def exec(func: => Int) = func   
  2. exec: (=> Int)Int
  3. // by-name-parameters are executed when they are referenced
  4. // so the result is 10
  5. scala> exec {10}                    
  6. res3: Int = 10
  7. // This is not legal because by-name-parameters
  8. // are not normal functions
  9. scala> def exec(func: => Int) = func()
  10. <console>:4: error: func of type Int does not take parameters
  11.        def exec(func: => Int) = func()

So the issue is how can you pass a by-name-parameter to a method that takes a function as a parameter without having to do:
  1. scala> def takesFunc(func: () => Int) = println(func())
  2. takesFunc: (() => Int)Unit
  3. scala> def send(x: => Int) = takesFunc(() => x) 
  4. send: (=> Int)Unit
  5. scala> send{2}
  6. 2

the alternative syntax is:
  1. scala> def send(x: => Int) = takesFunc (x _)   
  2. send: (=> Int)Unit
  3. scala> send {2}
  4. 2

Sunday, December 13, 2009

Danger: Shadowed member values

It is possible (although not recommended) to declare a public property in a super class and have a private value or variable in a subclass:
  1. scala> class X (val i:Int)
  2. defined class X
  3. scala> class Y(i:Intextends X(19) {
  4.      | println(i)
  5.      | }
  6. defined class Y
  7. scala> val y = new Y(100)
  8. 100
  9. y: Y = Y@3e55a58f
  10. scala> y.i
  11. res7: Int = 19

This begs the question: how can the subclass access the superclass instance of i? Let me re-iterate. Just because it is possible this is a bad idea. This pattern seems like it is begging to create bugs. But who knows there is probably some reason out there where this is required.

The way to access the X.i value from Y is to declare which value you want using the syntax this:X :
  1. scala> class Y(i:Intextends X(19) {
  2.      | println("Y.i"+i)              
  3.      | println("X.i"+(this:X).i)
  4.      | }
  5. defined class Y
  6. scala> new Y(39)
  7. Y.i39
  8. X.i19
  9. res8: Y = Y@451dfada

Repeat: Watch out! Because I learned this danger while writing this topic:
  1. scala> class Y(i:Intextends X(19) {
  2.      | println("1. "+i)              
  3.      | println("2. "+this.i)         
  4.      | println("3. "+(this:Y).i)     
  5.      | println("4. "+(this:X).i)     
  6.      | }
  7. defined class Y
  8. scala> new Y(44)
  9. 1. 44
  10. 2. 44
  11. 3. 19  // this is created via (this:Y).i !
  12. 4. 19
  13. res0: Y = Y@338bd37a

It seems that the syntax (this:X).i accesses the public accessor for i. The public access is a method call I think so it always obtains the value for the property. Shocking!

Thursday, December 10, 2009

XML transformations 2

This topic is a continuation of XML Transformations. The previous topic showed a method of creating transformation rules then combining the rules to create a transformation that could be applied to an XML datastructure. This topic takes a different approach of
using a match statement an a recursive method to iterate through the tree.
  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> def moveElements (node:Node) : Node = node match {
  25.      | case n:Elem if (n.label == "videos") => 
  26.      |   n.copy( child = n.child diff mislabelledBooks)
  27.      | case n:Elem if (n.label == "books") =>
  28.      |   val newBooks = mislabelledBooks map { e => e.asInstanceOf[Elem].copy(label="book") }
  29.      |   n.copy( child = n.child ++ newBooks)
  30.      | case n:Elem => 
  31.      |   val children = n.child map {moveElements _}
  32.      |   n.copy(child = children)
  33.      | case n => n
  34.      | }
  35. moveElements: (node: scala.xml.Node)scala.xml.Node
  36. scala> moveElements(xml)
  37. res1: scala.xml.Node = 
  38. <library>
  39.               <videos>
  40.               <video type="dvd">Seven</video>
  41.               <video type="blue-ray">The fifth element</video>
  42.               
  43.               </videos>
  44.               <books>
  45.               <book type="softcover">Memories of Ice</book>
  46.               <book type="hardcover">Gardens of the moon</book></books>
  47.               </library>

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]