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

Tuesday, February 9, 2010

Structural Types: Multiple Methods and Type Aliasing

There are two more aspects related to structural typing that are useful to look at. Structural types with multiple methods and type aliases.

For background on this topic also look at:
Structural Types are not limited to defining a single method. In that regard they are very similar to interfaces without the binary incompatibility issues. However do not be fooled into thinking they are the same thing. For one reason reflection is used so performance can be an issue in certain cases and also interfaces/traits have semantics that structural types do not.
  1. /*
  2. Defining a types that has both a length and charAt method.  
  3. Just a warning.  If you leave off the () after length this will not work.  This is not a bug.  Martin kindly left a comment on why it is not.
  4. */
  5. scala> def foreach(t : {def length():Intdef charAt(i:Int):Char}, f : Char => Unit) = {
  6.      | 0 until t.length foreach {i => f(t.charAt(i))}  
  7.      | }
  8. foreach: (t: AnyRef{def length(): Intdef charAt(i: Int): Char},f: (Char) => Unit)Unit
  9. // A string matches the structural type
  10. scala> foreach ("hello", println _)
  11. h
  12. e
  13. l
  14. l
  15. o

Pretty unexpected I would say. A feature of Scala which complements Structural types are type aliases. They are useful in many situations and one is with use with Structural Types:
  1. /*
  2. With type aliasing you can assign a structural type a name
  3. */
  4. scala> type IChar = {def length():Int
  5.      |               def charAt(i:Int):Char}
  6. defined type alias IChar
  7. scala> def print( t : IChar) = 0 until t.length() foreach {i => println(t.charAt(i))}
  8. print: (t: IChar)Unit
  9. scala> print("gurk")
  10. g
  11. u
  12. r
  13. k

Monday, February 8, 2010

Dynamic calls using Structural Types

Using reflection can be a real pain in Java since the API is a Java API and consists of many gets and searches through collections not to mention so many exceptions that need to be handled. In Scala there is a wonderful way to clean up a reflective call down to a single line (assuming you don't want to worry about handling exceptions.) Here structural typing can really be a pleasure.
  1. // I am assigning a string to an Any reference
  2. scala> val s:Any = "hello :D"
  3. s: Any = hello :D
  4. // Any does not have a length method
  5. scala> s.length
  6. < console>:6: error: value length is not a member of Any
  7.        s.length
  8.          ^
  9. /*
  10. But I can cast it to a structural type with a length method
  11. */
  12. scala> s.asInstanceOf[{def length:Int}].length
  13. res2: Int = 8

There are restrictions to this. For example implicits will not work:
  1. /*
  2. The method r is part of StringLike (or RichString in Scala 2.7) 
  3. and there is an implicit conversion from String to RichString/StringLike.
  4. The structural type does not try to apply the implicits because implicits are a
  5. compile time artifact and that information is not kept at run time.  Perhaps this
  6. will be added in the future but it is not present now.
  7. */
  8. scala> s.asInstanceOf[{def r:util.matching.Regex}].r
  9. java.lang.NoSuchMethodException: java.lang.String.r()

More examples:
  1. scala> val s:Any = "hello :D"
  2. s: Any = hello :D
  3. scala> s.asInstanceOf[{def charAt(x:Int):Char}].charAt(2)
  4. res9: Char = l
  5. /*
  6. This is interesting.  The actual method returns Char, but Char is
  7. compatible with Any so this cast works.
  8. */
  9. scala> s.asInstanceOf[{def charAt(x:Int):Any}].charAt(2) 
  10. res10: Any = l
  11. // Now lets test to see if that lenience is available for parameters:
  12. scala> class X 
  13. defined class X
  14. scala> class Y extends X
  15. defined class Y
  16. scala> class T {
  17.      | def x(x:X):Int = 1
  18.      | }
  19. defined class T
  20. scala> val a:Any = new T()
  21. a: Any = T@687c3b99
  22. scala> a.asInstanceOf[{def x(x:X):Any}].x(new Y())
  23. res11: Any = 1
  24. /*
  25. Ok so return values can be subclasses but not params
  26. */
  27. scala> a.asInstanceOf[{def x(x:Y):Any}].x(new Y())
  28. java.lang.NoSuchMethodException: T.x(Y)
  29. at java.lang.Class.getMethod(Class.ja

Use with care :-D

Friday, February 5, 2010

Introducing Structural Types

Structural types allows one to declare types based on the methods the type has. For example you could define a method that takes a class containing a close method. This is fairy analogous to duck-typing in dynamic languages. Except that it is statically enforced.

The main example used here was from a comment on the Code Monkeyism Blog. The commenter further explains that this example is in fact from Beginning Scala chapter 4 (which I would like to read but have not yet had the time.)
  1. /*
  2. A can be any object that has a close method.  
  3. This is statically typed which makes some restrictions which are explained later
  4. */
  5. scala> def using[A <: {def close(): Unit}, B](param: A)(f: A => B): B = 
  6.      | try {
  7.      |     f(param)
  8.      |   } finally {
  9.      |     try {
  10.      |        param.close()
  11.      |     } catch { case _ => () }
  12.      |   }
  13. using: [A <: AnyRef{def close(): Unit},B](param: => A)(f: (A) => B)B
  14. scala> using(new java.io.ByteArrayInputStream("hello world".getBytes)){ in => 
  15.      | io.Source.fromInputStream(in) foreach (print)                          
  16.      | }
  17. hello world
  18. scala> using(new java.io.ByteArrayInputStream("hello world".getBytes)){ in => 
  19.      | io.Source.fromInputStream(in) mkString ""                              
  20.      | }
  21. res8: String = hello world

That is extremely powerful and the consequences will be visited more in the future. But because structural typing is statically enforced it is not quite as flexible as dynamic language's version of duck typing. For example you cannot do:
  1. scala> val i:Any = new java.io.ByteArrayInputStream("hello world".getBytes)
  2. i: Any = java.io.ByteArrayInputStream@145a25f3
  3. /*
  4. This does not work because 'i' is defined as type Any.  Not a type that is closeable.  
  5. Casting can be used to get around this issue.  I will address that in its own post
  6. */
  7. scala> using(i){ in => 
  8.      | io.Source.fromInputStream(in) mkString ""
  9.      | }
  10. < console>:8: error: inferred type arguments [Any,B] do not conform to method using's type parameter bounds [A <: AnyRef{def close(): Unit},B]
  11.        using(i){ in =>

An alternative to the first using example is to use call by name to construct the closeable. The reason one might want to do that is because it allows currying of the method:
  1. scala> def using[A <: {def close(): Unit}, B](param: =>A)(f: A => B): B = 
  2.      | val closeable = param  // notice param is only referenced once
  3.      | try {
  4.      |     f(closeable)
  5.      |   } finally {
  6.      |     try {
  7.      |        closeable.close()
  8.      |     } catch { case _ => () }
  9.      |   }
  10. using: [A <: AnyRef{def close(): Unit},B](param: => A)(f: (A) => B)B
  11. /*
  12. if this was accessing a database a new connection would be made automatically each time this function was used
  13. */
  14. scala> val usingTheWorld = using[BStream,Int](new java.io.ByteArrayInputStream("hello world".getBytes))_
  15. usingTheWorld: ((java.io.ByteArrayInputStream) => Int) => Int = < function1>
  16. scala> usingTheWorld { s => io.Source.fromInputStream(s).length}  
  17. res3: Int = 11
  18. scala> usingTheWorld { s => io.Source.fromInputStream(s).getLines().length}
  19. res5: Int = 0

Wednesday, February 3, 2010

Regex ReplaceAllIn

Note: Updated on Feb 13th for the newer API on Scala 2.8 trunk. (This is life on the bleeding edge, thanks Daniel).

A couple new methods have just been added to Scala 2.8 Regex. You will need to download a version of Scala 2.8 more recent than Scala2.8-Beta1.

The methods are related to replacing text using a regular expression and to say they are useful is an understatement. Lets take a look:
  1. scala> val quote = """I don't like to commit myself about heaven and hell - you see, I have friends in both places. 
  2.      | Mark Twain"""                                                                                                
  3. quote: java.lang.String = 
  4. I don't like to commit myself about heaven and hell - you see, I have friends in both places. 
  5. Mark Twain
  6. scala> val expr = "e".r    
  7. expr: scala.util.matching.Regex = e
  8. /* 
  9. This first method is not new or is it interesting.  But the new methods are both related
  10. so lets start with the basic form of replaceAllIn
  11. */
  12. scala> expr.replaceAllIn(quote, "**")
  13. res1: String = 
  14. I don't lik** to commit mys**lf about h**av**n and h**ll - you s****, I hav** fri**nds in both plac**s. 
  15. Mark Twain
  16. // this does the same thing
  17. scala> quote.replaceAll("e","**")
  18. res2: java.lang.String = 
  19. I don't lik** to commit mys**lf about h**av**n and h**ll - you s****, I hav** fri**nds in both plac**s. 
  20. Mark Twain
  21. /*
  22. Now things get interesting.  Using this form of replaceAllIn we can determine the replacement on a case by case basis.
  23. It provides the Match object as the parameter so you have complete access to all 
  24. the matched groups, the location of the match etc...
  25. The method takes a Match => String function.  Very, very powerful.
  26. */
  27. scala> expr.replaceAllIn(quote, s => if(util.Random.nextBoolean) "?" else "*")
  28. res5: String = 
  29. I don't lik? to commit mys?lf about h?av?n and h?ll - you s*?, I hav? fri*nds in both plac*s. 
  30. Mark Twain
  31. /*
  32. Another example using some of the matcher functionality
  33. */
  34. scala> expr.replaceAllIn(quote, m => m.start.toString)                        
  35. res6: String = 
  36. I don't lik11 to commit mys26lf about h37av40n and h48ll - you s5960, I hav68 fri73nds in both plac90s. 
  37. Mark Twain
  38. /*
  39. Another crazy useful method is the replaceSomeIn.  It is similar to the replaceAllIn that takes a function except that the function in replaceSomeIn returns an Option.  If None then there is no replacement.  Otherwise a replacement is performed.  Very nice when dealing with complex regular expressions.
  40. In this example we are replacing all 'e's start are before the 50th character in the string with -
  41. */
  42. scala> expr.replaceSomeIn(quote, m => if(m.start > 50) None else Some("-"))
  43. res3: String = 
  44. I don't lik- to commit mys-lf about h-av-n and h-ll - you see, I have friends in both places.
  45. Mark Twain

Chaining Options with orElse

A simple but handy use for Option is to select the first valid option from a selection of possible choices. Sound vague? Well it is because it can be used in many different situations. The one presented here is: the program needs a directory that can be set by the user either as a system variable, and environment variable or the default value. The java code is a nightmare of if (xxx == null) statements. The Scala code is beautiful.
  1. scala> val propsTemplates = Option(System getProperty "MVN_CREATOR_TEMPLATES")
  2. propsTemplates: Option[java.lang.String] = None
  3. scala> val envTemplates = Option(System getenv "MVN_CREATOR_TEMPLATES")
  4. envTemplates: Option[java.lang.String] = None
  5. scala> val defaultHome = Some(System getProperty "user.home")
  6. defaultHome: Some[java.lang.String] = Some(/Users/jeichar)
  7. /* 
  8. chain the different options together in order of priority and get the value
  9. I am taking a small liberty here because I am assuming that user.home is always available
  10. */
  11. scala> propsTemplates.orElse(envTemplates).orElse(defaultHome).get
  12. res0: java.lang.String = /Users/jeichar
  13. // alternative form:
  14. scala> propsTemplates orElse envTemplates orElse defaultHome get
  15. res1: java.lang.String = /Users/jeichar

Tuesday, February 2, 2010

Blocks within for-comprehensions

In another example of uniformity it is possible to use blocks within a for-comprehension when creating a generator or making an assignment. The basic form of a for-comprehension is
  1. for {i <- generator 
  2.      if guard
  3.      j = assignment } yield result

The generator, guard, assignment and result are all expressions which means they can all be blocks or simple statements. Most commonly you will see them as simple statements:
  1. scala> for {i <- 1 to 10
  2.      |      if i % 2 == 0
  3.      |      j = i } yield j
  4. res50: scala.collection.immutable.IndexedSeq[Int] = IndexedSeq(2, 4, 6, 8, 10)

But since they are expressions they can be more complex:
  1. scala> for {  
  2.      |  i <- { 
  3.      |     val start = nextInt(3)
  4.      |     val end = nextInt(10)+start
  5.      |     start to end
  6.      |  }
  7.      |  if {
  8.      |    val cut = nextInt(3)+1
  9.      |    i % cut == 0
  10.      |  }
  11.      |  j = {
  12.      |    val x = i+1
  13.      |    x / 2
  14.      |  }
  15.      |  }  yield {
  16.      |    // do a debug println
  17.      |    println(j)
  18.      |  j
  19.      |  }
  20. 1
  21. 1
  22. 2
  23. 3
  24. res53: scala.collection.immutable.IndexedSeq[Int] = IndexedSeq(1, 1, 2, 3)

Monday, February 1, 2010

Temporary variables during object instantiation

In Java a common pattern with class constructors is to assign field values and often there are several intermediate values used for the calculation. If the code is ported to Scala the resulting class will have the intermediate values as fields, which take up space in the object. However the issue is easily worked around. Lets look at a couple examples.

Example 1: Assigning a single field
  1. //  Java
  2. import java.io.File
  3. /** 
  4. No real logic behind class.  But for some reason it needs the path of a tmp directory in the working directory
  5. */
  6. class OneAssignment {
  7.   final String field;
  8.   public OneAssignment() {
  9.     File file = new File("tmp");
  10.     if(!file.exists()) {
  11.       file.mkdirs();
  12.     }
  13.     field = file.getAbsolutePath();
  14.   }
  15. }

In Scala the naive way to port this would be:
  1. //  Scala
  2. import java.io.File
  3. class OneAssignment {
  4.   val file = new File("tmp")
  5.   if(!file.exists()) {
  6.     file.mkdirs()
  7.   }
  8.   val field = file.getAbsolutePath()
  9. }

Problem is that it has an extra field "file" now. The correct way to port this would be as follows:
  1. //  Scala
  2. import java.io.File
  3. class OneAssignment {
  4. /* 
  5. notice that assignment is in a block so file is only visible within the block
  6. */
  7.   val field = {
  8.     val file = new File("tmp")
  9.     if(!file.exists()) {
  10.       file.mkdirs()
  11.     }
  12.     file.getAbsolutePath()
  13.   }
  14. }


Example 2: Assigning multiple fields
  1. //  Java
  2. import java.io.File
  3. /** 
  4. Basically the same as last example but multiple fields are assigned
  5. Notice that 2 fields depend on the temporary file variable but count does not
  6. */
  7. class MultipleAssignments {
  8.   final String tmp,mvn_repo;
  9.   find int count;
  10.   public OneAssignment() {
  11.     File file = new File("tmp");
  12.     if(!file.exists()) {
  13.       file.mkdirs();
  14.     }
  15.     tmp = file.getAbsolutePath();
  16.     count = file.listFiles.length;
  17.     
  18.     File home = new File(System.getProperty("user.home"));
  19.     mvn_repo = new File(home, ".m2").getPath();
  20.   }
  21. }

The Scala port:
  1. //  Scala
  2. import java.io.File
  3. class MultipleAssignments {
  4. /*
  5. When multiple fields depend on the same temporary variables the fields can be assigned together from one block by returning a tuple and using Scala's matching to expand the tuple during assignment.  See previous topics on assignment for details 
  6. */
  7.   val (tmp,count) = {
  8.     val file = new File("tmp");
  9.     if(!file.exists()) {
  10.       file.mkdirs();
  11.     }
  12.     val tmp = file.getAbsolutePath();
  13.     val count = file.listFiles.length;
  14.     (tmp, count)
  15.   }
  16.   val mvn_repo = {
  17.     val home = new File(System.getProperty("user.home"));
  18.     new File(home, ".m2").getPath();
  19.   }
  20. }

In some ways the Scala port is cleaner in that it splits the constructor up and decouples the dependencies between fields.