Monday, February 22, 2010

Methods of PartialFunction object

This topic looks at the functionality provide in the object PartialFunction.

This example uses Scala 2.8 which I believe is required.

Only two methods are focused on. PartialFunction.cond and PartialFunction.condOpt.
As per request the signature for said methods are:
  1. def cond[T](x: T)(pf: PartialFunction[T, Boolean]): Boolean
  2. def condOpt[T, U](x: T)(pf: PartialFunction[T, U]): Option[U]

Now for some examples:
  1. scala>  import PartialFunction._
  2. import PartialFunction._
  3. scala> def strangeConditional(other: Any): Boolean = cond(other) {
  4.      |  case x: String if x == "abc" || x == "def"  => true
  5.      |  case x: Int => true
  6.      | }
  7. strangeConditional: (other: Any)Boolean
  8. scala> strangeConditional("abc")
  9. res0: Boolean = true
  10. scala> strangeConditional("hello")
  11. res1: Boolean = false
  12. scala> strangeConditional(3)      
  13. res2: Boolean = true
  14. scala> def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x }
  15. onlyInt: (v: Any)Option[Int]
  16. scala> onlyInt("hi")
  17. res3: Option[Int] = None
  18. scala> onlyInt(3)
  19. res4: Option[Int] = Some(3)
  20. scala> import util.control.Exception.catching
  21. import util.control.Exception.catching
  22. scala> object IntNum { 
  23.      |  val number = catching(classOf[NumberFormatException])
  24.      |  def unapply(x : Any) = condOpt(x) {
  25.      |      case x : Int => x
  26.      |      case y : String if number.opt(y.toInt).isDefined => y.toInt
  27.      |    }
  28.      | }
  29. defined module IntNum
  30. scala> 1 match { case IntNum(x) => println(x+" i win!")}   
  31. 1 i win!
  32. scala> 3 match { case IntNum(x) => println(x+" i win!")}
  33. 3 i win!

Friday, February 19, 2010

=>? type alias for PartialFunction

A big thanks to Ben Jackman for this tip.

His tip cleans up the examples in post Chaining Partial Functions with orElse
The secret is to define the type alias type =>?[-A, +B] = PartialFunction[A, B]. This alias may be added to Predef in the future but until it is you can add it yourself.
  1. scala> type =>?[-A, +B] = PartialFunction[A, B]
  2. defined type alias $eq$greater$qmark
  3. scala> val i : (Any =>? Unit) = {case x:Int => println("int found")}
  4. i: =>?[Any,Unit] = < function1>
  5. scala> val j : (Any =>? Unit) = {case x:Double => println("Double found")}
  6. j: =>?[Any,Unit] = < function1>
  7. scala> val * : (Any =>? Unit) = {case x=> println("Something else found")}
  8. *: =>?[Any,Unit] = < function1>
  9. scala> (i orElse j orElse *)(1)
  10. int found
  11. scala> (i orElse j orElse *)(1.0)
  12. Double found
  13. scala> (i orElse j orElse *)(true)
  14. Something else found
  15. scala> def =>?[A, B](id : A =>? B) = id
  16. $eq$greater$qmark: [A,B](id: =>?[A,B])=>?[A,B]
  17. scala> ( =>?[Any, Unit]{case s : String => println("String found")} orElse j orElse *)("hello")
  18. String found

Thursday, February 18, 2010

Chaining Partial Functions with orElse

PartialFunctions are extremely valuable Scala constructs that are used in many APIs. Commonly you will encounter the pattern:
  1. obj match {
  2. case "Val" => // do something
  3. case _ => // handle all other cases
  4. }

It is intuitive and obvious how to share the code of the right hand side if the case statement by factoring that code out to a method. But would it not be useful to be able to factor out an entire case statement (PartialFunction) and later chain them together as needed?

This is indeed possible and very easy to do:
  1. /*
  2. We need to declare Partial Functions so to add brevity I am adding this alias
  3. */
  4. scala> import scala.{PartialFunction => PF}
  5. import scala.{PartialFunction=>PF}
  6. /*
  7. You have to explicitly declare the type because the type inferencer cannot know what type of PartialFunction to create
  8.  
  9. A PartialFunction is Strictly type so some functions can only be used on Ints for example
  10. */
  11. scala> val i : PF[Any, Unit] = {case x:Int => println("int found")}
  12. i: PartialFunction[Any,Unit] = < function1>
  13. scala> val j : PF[Any, Unit] =  {case x:Double => println("Double found")}
  14. j: PartialFunction[Any,Unit] = < function1>
  15. scala> val * : PF[Any, Unit] =  {case x=> println("Something else found")}
  16. *: PartialFunction[Any,Unit] = < function1>
  17. /*
  18. one might think that you can do:
  19. 1 match (i orElse j orElse *)
  20. but in fact (i orElse j orElse *) forms a PartialFunction not a pattern so cannot be used with match.  Instead it must be used as a function
  21. */
  22. scala> (i orElse j orElse *)(1)
  23. int found
  24. scala> (i orElse j orElse *)(1.0)
  25. Double found
  26. scala> (i orElse j orElse *)(true)
  27. Something else found
  28. /*
  29. for specific cases it is possible to chain the an anonymous partial function with the common function
  30. This is not so nice so it is probably best to declare a val instead of inline like this
  31. */
  32. scala> (({case s:String => println("String found")}:PF[Any,Unit]) orElse j orElse *)("hello")
  33. String found

For another example of chaining PartialFunctions the Akka tutorial has a good example in the ChatServer trait: http://jonasboner.com/2010/01/04/introducing-akka.html

Tuesday, February 16, 2010

And Case Statements

Recently I encountered a good question on Stack Overflow about matching.
http://stackoverflow.com/questions/2261358/pattern-matching-with-conjunctions-patterna-and-patternb.

As mentioned in an earlier post Matching with Or case expressions suppose 'or' expression combination using the '|' character. However 'and' combinations are not possible.

One solution is to build an && extractor object as follows:
  1. scala> case object && {  def unapply[A](a: A) = Some((a, a))}
  2. defined module $amp$amp
  3. scala> object StartsWith {  def unapply(s: String) = s.headOption}
  4. defined module StartsWith
  5. scala> object EndsWith {  def unapply(s: String) = s.reverse.headOption}
  6. defined module EndsWith
  7. scala> "foo" match {  case StartsWith('f') && EndsWith('o') => println("f*o") }
  8. f*o

Note: this is a scala 2.7 solution Scala 2.8 can be used to improve the EndsWith extractor by using the method lastOption instead of s.reverse.headOption.

Monday, February 15, 2010

Self Annotation vs inheritance

At first glance the "sself annotation" declaration seems similar to extending another class. (For a look at self annotations read the topic: Self Type.) They are completely different but the comparison is understandable since both of them provide access to the functionality of referenced class.

For example both of the following compile:
  1. class Base {
  2.   def magic = "bibbity bobbity boo!!"
  3. }
  4. trait Extender extends Base {
  5.   def myMethod = "I can "+magic
  6. }
  7. trait SelfTyper {
  8.   self : Base => 
  9.   
  10.   def myMethod = "I can "+magic
  11. }

But the two are completely different. Extender can be mixed in with any class and adds both the "magic" and "myMethod" to the class it is mixed with. SelfType can only be mixed in with a class that extends Base and SelfTyper only adds the method "myMethod" NOT "magic".

Why is the "self annotations" useful? Because it allows several provides a way of declaring dependencies. One can think of the self annotation declaration as the phrase "I am useable with" or "I require a".

The following example demonstrates one possible reason to use self annotations instead of extend.

Note: These examples can be pasted into the REPL but I have shown that here because it would make the examples too long.
  1. import java.io._
  2. import java.util.{Properties => JProps}
  3. trait Properties {
  4.   def apply(key:String) : String
  5. }
  6. trait XmlProperties extends Properties {
  7.   import scala.xml._
  8.   
  9.   def xml(key:String) = Elem(null,key,Null,TopScope, Text(apply(key)))
  10. }
  11. trait JSonProperties extends Properties {
  12.   def json(key:String) : String = "%s : %s".format(key, apply(key))
  13. }
  14. trait StreamProperties {
  15.   self : Properties => 
  16.   
  17.   protected def source : InputStream
  18.   
  19.   private val props = new JProps()
  20.   props.load(source)
  21.   
  22.   def apply(key:String) = props.get(key).asInstanceOf[String]
  23. }
  24. trait MapProperties {
  25.   self : Properties =>
  26.   
  27.   protected def source : Map[String,String]
  28.   def apply(key:String) = source.apply(key)
  29. }
  30. val sampleMap = Map("1" -> "one""2" -> "two""3" -> "three")
  31. val sampleData = """1=one
  32.                     2=two
  33.                     3=three"""
  34. val sXml = new XmlProperties() with StreamProperties{
  35.               def source = new ByteArrayInputStream(sampleData.getBytes)
  36.            }
  37. val mXml = new XmlProperties() with MapProperties{
  38.               def source = sampleMap
  39.            }
  40. val sJSon = new JSonProperties() with StreamProperties{
  41.               def source = new ByteArrayInputStream(sampleData.getBytes)
  42.             }
  43. val mJSon = new JSonProperties() with MapProperties{
  44.               def source = sampleMap
  45.             }
  46. sXml.xml("1")
  47. mXml.xml("2")
  48. sJSon.json("1")
  49. mJSon.json("2")

The justification for using self annotations here is flexibility. A couple other solutions would be
  1. Use subclassing - this is poor solution because there would be an explosion of classes. Instead of having 5 traits you would need 7 traits. Properties, XmlProperties, JSonProperties, XmlStreamProperties, XmlMapProperties, JsonStreamProperties and JsonMapProperties. And if you later wanted to add a new type of properties or a new source like reading from a database then you need 2 new subclasses.
  2. Composition - Another strategy is to use construct the XmlProperties with a strategy that reads from the source. This is essentially the same mechanism except that you need to build and maintain the the dependencies. It also makes layering more difficult. For example:
    1. trait IterableXmlProperties {                                            
    2.     self : MapProperties with XmlProperties => 
    3.     def xmlIterable = source.keySet map {xml _}
    4.   }
    5.   
    6.   new XmlProperties with MapProperties with IterableXmlProperties {def source = sampleMap}

The next question that comes to mind is why use extends then if self annotation is so flexible? My answer (and I welcome discussion on this point) has three points.
  1. The first is of semantics and modeling. When designing a model it is often more logical to use inheritance because of the semantics that comes with inheriting from another object.
  2. Another argument is pragmatism.
    Imagine the collections library where there is no inheritance. If you wanted a map with Iterable functionality you would have to always declare Traversable with Iterable with Map (and this is greatly simplified). That declaration would have to be used for virtually all methods that require both the Iterable and Map functionality. To say that is impractical is an understatement. Also the semantics of Map is changed from what it is now. The trait Map currently includes the concept of Iterable.
  3. The last point is sealed traits/classes. When a trait is "sealed" all of its subclasses are declared within the same file and that makes the set of subclasses finite which allows certain compiler checks. This (as far as I know) cannot be done with self annotations.

Friday, February 12, 2010

Specs and Fixtures/Contexts

This topic revisits the Specs BDD testing library. It is a continuation of the previous post Specs BDD Testing Framework.

This topic will look at how to setup fixtures in Specs. This is only a sample to give a feeling of Specs a much more complete guide is available on the Specs website.
  1. jeichar: git-src$ 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. /*
  5. This example demonstrates before and after actions similar to what is found in XUnit.
  6. */
  7. scala> object mySpec extends Specification {           
  8.      | "my system" should {
  9.      | doFirst{println("before")}  // ran once
  10.      | 
  11.      | doBefore{println("before")} // ran for each test
  12.      | doAfter{println("after")} // ran for each test
  13.      | 
  14.      | "test spec 1" in { println("test1"); 1 must_== 1}
  15.      | "test spec 2" in { println("test2"); 1 must_== 2}
  16.      | 
  17.      | doLast{println("last")} // ran once
  18.      | }}
  19. defined module mySpec
  20. scala> mySpec.main(Array())                             
  21. Specification "mySpec"
  22.   my system should
  23. before
  24. before
  25. test1
  26. after
  27.   + test spec 1
  28. before
  29. test2
  30. after
  31. last
  32.   x test spec 2
  33.     '1' is not equal to '2' (< console>:14)
  34. Total for specification "mySpec":
  35. Finished in 0 second, 307 ms
  36. 2 examples, 2 expectations, 1 failure, 0 error

Example using Contexts there many more examples at: Shared contexts
  1. scala> import org.specs._
  2. import org.specs._
  3. /*
  4. This specification uses contexts instead of before and after actions.
  5. My personal preference is to use contexts because they are more flexible and can have names associated with them.  In addition contexts can be shared between specifications and multiple contexts can be used within a single specification.  This example is kept very simple for demonstration purposes
  6. */
  7. scala> object StackSpecification extends Specification {
  8.      |   var list : List[Int] = _
  9.      |   val empty = beforeContext(list = Nil)  
  10.      |   val nonEmpty = beforeContext(list = List(1,2,3))
  11.      |   
  12.      |   "A full stack" definedAs nonEmpty should { 
  13.      |     "size of 3" in {
  14.      |       list must haveSize (3)
  15.      |     }
  16.      |   }
  17.      |   "A stack" when empty should { 
  18.      |     "is empty" in {
  19.      |       list must beEmpty
  20.      |     }
  21.      |   }
  22.      | }
  23. defined module StackSpecification
  24. scala> StackSpecification.main(Array())
  25. Specification "StackSpecification"
  26.   A full stack should
  27.   + size of 3
  28.   Total for SUS "A full stack":
  29.   Finished in 0 second, 42 ms
  30.   1 example, 1 expectation, 0 failure, 0 error
  31.   A stack should
  32.   + is empty
  33.   Total for SUS "A stack":
  34.   Finished in 0 second, 4 ms
  35.   1 example, 1 expectation, 0 failure, 0 error
  36. Total for specification "StackSpecification":
  37. Finished in 0 second, 85 ms
  38. 2 examples, 2 expectations, 0 failure, 0 error

Thursday, February 11, 2010

Selection with Implicit Methods

This tip is a cool tip based on Daniel's Use Implicits to Select Types post. That post goes into more detail.

The idea is that depending on a given parameter of type T a particular type of object is required. There are several ways to do this. One would be to use matching to match the type T and create the correct object. Most likely the biggest draw back to matching is caused by type erasure. The following solution gets around that issue.

Two very interesting points.
  1. Implicit methods do not require parameters. They can be selected based only on type parameters
  2. Implicit methods are not subject to type erasure
  1. // the base class we need
  2. scala> abstract class X[T] { def id :Unit }
  3. defined class X
  4. /*
  5. One of the types we need created.  It is the catch all case
  6. */
  7. scala> implicit def a[T] =new X[T] { def id =println("generic") }
  8. a: [T]X[T]
  9. /*
  10. A specific subclass for integers
  11. */
  12. scala> implicit def b =new X[Int] { def id =println("Int") }
  13. b: X[Int]
  14. /*
  15. One simple usage.  The most specific implicit will be used to 
  16. create the object to be passed to g.  
  17. */
  18. scala> def f[T](a :T)(implicit g :X[T]) = g.id
  19. f: [T](a: T)(implicit g: X[T])Unit
  20. scala> f(5)
  21. Int
  22. scala> f('c')
  23. generic
  24. /*
  25. This example demonstrates how erasure is not an issue because 
  26. the selection of the implicit is done at compile time so 
  27. the correct type is selected.  If a match was used instead 
  28. then a more complicated solution would be required
  29. */
  30. scala> def g[T](l:List[T])(implicit i:X[T]) = i.id          
  31. g: [T](l: List[T])(implicit i: X[T])Unit
  32. scala> g(List(1,2,3))
  33. Int
  34. scala> g(List("a",2,3))
  35. generic