Monday, November 30, 2009

Overloaded Unapply

This topic is related to previous posts on matching. I recommend reading some of them as well:
Since an Extactor is just an object with an unapply method it logically follows that an Extractor can have an overloaded unapply method. In other words can have an unapply(String) and an unapply(Int); allowing matching Strings and Ints.
  1. scala> object T{                                                         
  2.      |  def unapply(v:String)= if(v== "s") Some("yay") else None
  3.      |  def unapply(v:Int) = if(v==1) Some("hmmm") else None
  4.      | }
  5. defined module T
  6. scala> 1 match { case T(x) => println(x) }
  7. hmmm
  8. scala> "s" match { case T(x) => println(x) }
  9. yay
  10. scala> object T{                                 
  11.      | def unapplySeq(v:String) = if (v=="x") Some(List(1,2,3)) else None
  12.      | def unapplySeq(v:Int) = if (v==1) Some(List("one","two")) else None
  13.      | }
  14. defined module T
  15. scala>  "x"  match { case T(x,y,z) => println(x,y,z) }
  16. (1,2,3)
  17. scala>  1  match { case T(x,y) => println(x,y) }  
  18. (one,two)

Friday, November 27, 2009

Defining Custom Control Structures

Scala has only a handful of built-in control structures: for, while, try-catch, if, etc... However it is quite simple to define custom control structures. There are several good examples in the Scala 2.8 library. For some examples look at the classes in the scala.util.control package.

For this topic, we will develop a simplified version of the Exception class. First a demonstration of the 2.8 version.
  1. scala> import scala.util.control.Exception._
  2. import scala.util.control.Exception._
  3. scala> val numberFormat = catching(classOf[NumberFormatException])
  4. numberFormat: util.control.Exception.Catch[Nothing] = Catch(java.lang.NumberFormatException)
  5. scala> val result = numberFormat opt { "10".toInt }               
  6. result: Option[Int] = Some(10)
  7. scala> result match {
  8.      | case Some(n) => // do something
  9.      | case None => // handle this situation
  10.      |


A question that often arises when presented with the Exception control flow is why not use try-catch. There are two main reasons in my opinion.

First, people coming from certain functional style languages find that form more comfortable (so I have heard.) So in this case it is a style issue.

The other reason (and the one more pertinent to Java developers), is that it provides a nice way to handle common exceptions. Why do I say nice? First it declares when exceptions are handled before the code and that provides more context while reading the code. In addition, if you create the Catch object and assign it to a nicely named variable then it is clear what the intent is. For example there may be several reasons to catch a runtime exception and they should be handled differently. A few well-named variables can really assist in readability. A final point is that several of these variables can be defined in on object and shared throughout a project adding some consistency to a project.

Back to the topic at hand.

We will develop a simplified version: a catching method that will return Some(...) if no exception occurs or None if one of the declared exceptions has occurred or throw exception if the exception is not one we declare as handling. Now this is not what I would necessarily call a custom control flow because it does not offer a choice of execution flows. To do that I would add more components like int the Exceptions object. However, this is a good demonstration of the parts required to create a custom control struction. The key is the => in def method(arg: => T) This is a special type construct which means that a no param function is passed in but is not executed until called within the method. A few comparisons:
  1. scala> def method(arg: =>Int) = println(arg)
  2. method: (arg: => Int)Unit
  3. scala> def method2(arg: =>Int) = println("not calling arg")
  4. method2: (arg: => Int)Unit
  5. scala> var x = 1
  6. x: Int = 1
  7. // when method is called x is incremented because method calls the argument
  8. scala> method { x += 1; x }                                
  9. 2
  10. scala> println(x)          
  11. 2
  12. // when method2 is called x is not incremented because 
  13. // the argument is not called/referenced
  14. scala> method2 { x += 1; x }
  15. not calling arg
  16. scala> println(x)           
  17. 2
  18. // arg is referenced 2 times in method three so x is incremented 2 times
  19. scala> def method3(arg: => Int) = println("first call="+arg+" second call="+arg)
  20. method3: (arg: => Int)Unit
  21. scala> method3 { x += 1; x }                                                   
  22. first call=3 second call=4
  23. // Now demonstrate the standard way of defining arguments
  24. // the value passed is calculated before calling the method
  25. // so is at most called once
  26. scala> def byValue(arg: Int) = println(arg)
  27. byValue: (arg: Int)Unit
  28. scala> def byValue2(arg: Int) = println("not calling arg")
  29. byValue2: (arg: Int)Unit
  30. scala> def byValue3(arg: Int) = println("first call="+arg+" second call="+arg)
  31. byValue3: (arg: Int)Unit
  32. scala> byValue{ x += 1; x }
  33. 5
  34. scala> byValue2{ x += 1; x }
  35. not calling arg
  36. scala> println(x)
  37. 6
  38. scala> byValue3{ x += 1; x }
  39. first call=7 second call=7
  40. // And finally show the normal way to pass in a function. 
  41. // This has the benefit of allowing the reader of the code to
  42. // realize that the argument is a function
  43. // but is not a nice syntax for control flow
  44. scala> def stdFunc(arg: ()=>Int) = println(arg())
  45. stdFunc: (arg: () => Int)Unit
  46. scala> def stdFunc2(arg: ()=>Int) = println("not calling arg")
  47. stdFunc2: (arg: () => Int)Unit
  48. scdef stdFunc3(arg: ()=>Int) = println("first call="+arg()+" second call="+arg()) 
  49. stdFunc3: (arg: () => Int)Unit
  50. scala> stdFunc {() => x += 1; x }  
  51. 8
  52. scala> stdFunc2 {() => x += 1; x }
  53. not calling arg
  54. scala> println(x)
  55. 8
  56. scala> stdFunc3 {() => x += 1; x }
  57. first call=9 second call=10


Now for the complete catching example:
  1. scala> def catching[T](exceptions: Class[_]*)(body: => T) = {
  2.      | try {                                                 
  3.      | Some (body)                                           
  4.      | } catch {
  5.      | case e if (exceptions contains e.getClass) => None
  6.      | }                
  7.      | }
  8. catching: [T](exceptions: Class[_]*)(body: => T)Option[T]
  9. scala> val runtime = catching[Number](classOf[NullPointerException], classOf[NumberFormatException])_
  10. runtime: (=> java.lang.Number) => Option[java.lang.Number] = < function1>
  11. scala> runtime { "".toInt }                                                                          
  12. res2: Option[java.lang.Number] = None
  13. scala> runtime { "10".toInt }
  14. res3: Option[java.lang.Number] = Some(10)
  15. scala> runtime { throw new NullPointerException }
  16. res6: Option[java.lang.Number] = None
  17. scala> runtime { throw new RuntimeException }
  18. java.lang.RuntimeException
  19.         at $anonfun$1.apply(< console>:10)
  20.         at $anonfun$1.apply(< console>:10)
  21.         at .catching(< console>:9)
  22.         at $anonfun$1.apply(< console>:8)
  23.         at $anonfun$1.apply(< console>:8)
  24.         at .< init>(< console>:10)
  25.         at .< clinit>(< console>)
  26.         at RequestResult$.< init>(< console>:4)
  27.         at RequestResult$.< clinit>(< console>)
  28.         at RequestResult$result(< console>)
  29.         ...

Wednesday, November 25, 2009

Good Scala Style

This topic is a bit of a departure from the normal but is very important. The goal of these posts has not been(necessarily) to introduce good coding style, instead to introduce the different tools at your disposal. There have been some good styles to follow and some bad ones (hopefully more good than bad.) Today is mainly a link to a project and document that is documenting a style guide for Scala programming. I highly recommend taking a look at it and a big thanks to Daniel Spiewak for spearheading this project, although I think it has now grown beyond just Daniel so thanks to the other contributors as well.

Github project: http://github.com/davetron5000/scala-style
HTML - http://davetron5000.github.com/scala-style
PDF - http://davetron5000.github.com/scala-style/ScalaStyleGuide.pdf

Thanks again for a wonderful resource.

Varargs

Both Java and Scala have varargs. In Scala the syntax for a varargs argument is def method (param:String*). In the off-chance you are not aware of what varargs are; they allow an arbitrary number of values to be passed to the method. Some restrictions on when varargs can be used are:
  • The vararg parameter must be the last parameter in the list
  • There can not be default values for any parameters in the method containing the varargs (Scala 2.8+)

From the caller's point of view; varargs can be called as follows: method("p1", "p2", "p3") where the number of values is not limited. However, the () must be used.

In Java (if I remember right) only arrays can be passed in place of varargs:
  1. class C {
  2.   public static void main(String... args) {
  3.     System.out.println(args.length)
  4.   }
  5. }
  6. String[] args = new String[]{"arg1", "arg2"}
  7. C.main (args)

However Scala is more general and allows any sequence to be passed to varargs, with a caveat. When a sequence is passed to varargs a hint must be provided to indicate that you are intending to have the sequence be expanded to be the varargs.
  1. def method (args:Int*) = println(args)
  2. val list = List(1,2,3)
  3. method (list:_*)  // note the use of _*

Examples:
  1. scala> def method(varargs:Int*)(more:String*) = println(varargs,more)
  2. method: (Int*)(String*)Unit
  3. scala> method(1,2,3,4)("one")
  4. (Array(1, 2, 3, 4),Array(one))
  5. scala> method(1,2,3,4)       
  6. < console>:6: error: missing arguments for method method in object $iw;
  7. follow this method with '_' if you want to treat it as a partially applied function
  8.        method(1,2,3,4)
  9.        ^
  10. scala> method(1,2,3,4)()
  11. (Array(1, 2, 3, 4),Array())
  12. scala> method()("one")  
  13. (Array(),Array(one))
  14. scala> method("one")  
  15. < console>:6: error: type mismatch;
  16.  found   : java.lang.String("one")
  17.  required: Int
  18.        method("one")
  19.               ^
  20. scala> method()()     
  21. (Array(),Array())
  22. scala> val method2 = method(1,2,3)_  
  23. method2: (String*) => Unit = < function>
  24. scala> val paramList = List("hi","ho")
  25. paramList: List[java.lang.String] = List(hi, ho)
  26. scala> method2(paramList)
  27. < console>:8: error: type mismatch;
  28.  found   : List[java.lang.String]
  29.  required: String
  30.        method2(paramList)
  31.                ^
  32. scala> method2(paramList:_*)
  33. (Array(1, 2, 3),List(hi, ho))
  34. scala> val range = (1 to 5) map {_.toString} 
  35. range: RandomAccessSeq.Projection[java.lang.String] = RangeM(1, 2, 3, 4, 5)
  36. scala> method2(range:_*)                     
  37. (Array(1, 2, 3),RangeM(1, 2, 3, 4, 5))

Tuesday, November 24, 2009

Equals, Tuples and Case-classes

This is mostly a quick tip (or opportunity for refactoring).

Most of Scala's built in classes implement a useful equals and hashcode. The very commonly used case-classes and Tuple classes are the examples that spring to mind. So this enables the following options:
  1. // Assume Box is out of your control and you cannot refactor it into a case class
  2. scala> class Box(val name:String, val minx:Int, val miny:Int, val maxx:Int, val maxy:Int)
  3. defined class Box
  4. scala> val box = new Box("mybox", 0, 0, 10, 10)
  5. box: Box = Box@568bf3ec
  6. // before:
  7. scala> box.minx == 0 && box.miny == 0 && box.maxx == 10 && box.maxy == 10      
  8. res3: Boolean = true
  9. // after
  10. scala> import box._
  11. import box._
  12. scala> (minx,miny,maxx,maxy) == (0,0,10,10)
  13. res5: Boolean = true
  14. // another box definition:
  15. scala> case class Box2 (name:String, ul:(Int,Int), lr:(Int,Int)) 
  16. defined class Box2
  17. // case classes have nice equals for comparison
  18. scala> box2 == Box2("a nicer box", (0,0), (10,10))
  19. res6: Boolean = true
  20. // but what if you don't want to compare names
  21. scala> import box2._
  22. import box2._
  23. scala> (ul,lr) == ((0,0),(10,10))
  24. res7: Boolean = true

Sunday, November 22, 2009

Type aliasing and implicit conversions in harmony

This topic combines advanced two topics. types and implicit methods. This topic is not really intended to be instructional as much as a illustration of the cool stuff you can do with the language. As always becareful not to cut yourself :-)

In keeping with the uniform principle of Scala, types can defined as variables. This is useful for several reasons but this topic covers a cool/fun effect of having types be declared like variables. Type Aliasing. In the example below an alias | is created for the Either class. This allows the | to be used in place of Either.
  1. // Start of example 1.  creating the type alias
  2. // define the | type
  3. scala> type |[A,B] = Either[A,B]
  4. defined type alias $bar
  5. // If a Type has 2 parameters it can be used in operator form
  6. scala> Array[Int | Long](Left(5),Right(12L))
  7. res0: Array[|[Int,Long]] = Array(Left(5), Right(12))
  8. // start of example 2.  Simplify creation of an Array (or other collection) of either
  9. scala> implicit def makeLeft[A,B](a:A):Either[A,B] = Left(a)
  10. makeLeft: [A,B](a: A)Either[A,B]
  11. scala> implicit def makeRight[A,B](b:B):Either[A,B] = Right(b) 
  12. makeRight: [A,B](b: B)Either[A,B]
  13. // Since there are implicits to convert to Right and Left the values in the Array will be wrapped
  14. // automatically.  Makes the syntax MUCH cleaner and easier to read.
  15. scala> Array[Int|String](5,"Wurst",123,2,6)
  16. res1: Array[|[Int,String]] = Array(Left(5), Right(Wurst), Left(123), Left(2), Left(6))

Friday, November 20, 2009

Either

The Scala Either class is similar in function as Option but it represents a choice. For example a method can return Either an Int or an Exception. Usage example:
  1. // If string can be converted to an Int then return Right[Int] otherwise
  2. // return a Left[String] with the error message
  3. // by convention the error state will always be the Left
  4. scala> def toInt(string:String):Either[String,Int] = {
  5.      | try { Right(string.toInt) }
  6.      | catch { case e => Left("Error: "+e.getMessage) }
  7.      | }
  8. toInt: (string: String)Either[String,Int]
  9. scala> toInt("1")
  10. res0: Either[String,Int] = Right(1)
  11. scala> toInt("booger")
  12. res1: Either[String,Int] = Left(Error: For input string: "booger")

By convention if one return value is a error state and the other the expected state then Right will contain the expected state and Left will contain the error state.
  1. scala> def toInt(string:String):Either[String,Int] = {
  2.      | try { Right(string.toInt) }
  3.      | catch { case e => Left("Error: "+e.getMessage) }
  4.      | }
  5. toInt: (string: String)Either[String,Int]
  6. scala> toInt("1")
  7. res0: Either[String,Int] = Right(1)
  8. scala> toInt("booger")
  9. res1: Either[String,Int] = Left(Error: For input string: "booger")
  10. // you can test if the value is a left or right value quite easily
  11. scala> res0.isLeft
  12. res2: Boolean = false
  13. scala> res1.isRight
  14. res3: Boolean = false
  15. scala> res0.isRight
  16. res4: Boolean = true
  17. scala> res1.isLeft 
  18. res5: Boolean = true
  19. // or matching can be used
  20. scala> res0 match {                                   
  21.      | case Left(l) => println("it is a left")        
  22.      | case Right(r) => println("it is a right")      
  23.      | }
  24. it is a right
  25. scala> res1 match {                             
  26.      | case Left(l) => println("it is a left")  
  27.      | case Right(r) => println("it is a right")
  28.      | }
  29. it is a left
  30. // Perhaps cleaner than matching even is being able to pass 
  31. // functions to the fold method:
  32. // define one function for each side of the either
  33. // first the function to handle the left side case
  34. scala> def leftFunc(errMsg:String) = println("there has been an error")             
  35. leftFunc: (errMsg: String)Unit
  36. // next the function the handle the right side case
  37. scala> def rightFunc(i:Int) = println(i+" was calculated")              
  38. rightFunc: (i: Int)Unit
  39. // then you can pass the two functions to the fold method
  40. // and the correct one will be invoked
  41. scala> res0 fold (leftFunc _, rightFunc _)
  42. 1 was calculated
  43. scala> res1 fold (leftFunc _, rightFunc _)
  44. there has been an error