Scala Pattern Matching explained

Posted in java, scala, software development on April 26th, 2009 by Joerg – 1 Comment

I am currently reading Programming in Scala. For a programmer coming from an imperative world there many new concepts to learn. One of them is Pattern Matching. There are already lots of articles about it, but explaining something is still one of the best ways to learn. Here are the first 4 levels of understanding Pattern Matching.

Level 1 – Pattern Matching as simple switch/case replacement

Pattern Matching can simply be used to replace Java switch/case statements. This is called constant pattern and looks like this:

  def constantMatch(value:Any) = {
    value match {
      case "Hello" => "You said hello!"
      case 1 => "Oh, thats a 1!"
      case _ => "Don't know what you want!"
    }
  }

ConstantMatch is a function that takes a parameter of type Any. Any is the Scala pendant to java.lang.Object. This value is now matched against several constants. The first case is a String the second an Int and the last case is a wildcard for any other value.
There are a few differences to Java. First, there is no “fall through”. If a pattern has been matched its value will be returned. Thats the part after the => operator. This can be a full code block. The example above just shows the short version. The second difference is if no pattern matches Scala will throw a MatchError Exception. This is why the wildcard pattern is needed as the last line. This is more or less the same as the default clause of Java.

Level 2 – Introducing Variable patterns

Now level 1 was already more powerful than Java switch/case. But there are some more levels to go. The next step is introducing variable pattern. Here is an example:

 def variableMatch(value:Any) = {
    value match {
      case 1 =>"Oh, thats a 1!"
      case x =>"And thats a"+x+"!";
    }
  }

Instead of validating every possibly value the value itself is put into a variable. This variable can then be processed in the result block. You might recognize that there is no wildcard case(case _ => …). This is not necessary as the variable pattern will match any possible value. A wildcard would not even be possible. The compiler will complain that it is unreachable code.

Level 3 – Type Patterns

Type patterns allow to calculate the result based on the type of the value. Instead of using instanceof in Java or isInstanceOf in Scala this can just be done in a case statement. Let’s assume we have a class hierarchy used to calculate the financial value of different types of property.

abstract class Property {
  val value: BigDecimal
}

case class House(address: Address, override val value:BigDecimal) extends Property
case class Car(horsepower: Int, override val value:BigDecimal) extends Property
case class Horse(Age:Int, override val value:BigDecimal) extends Property
case class Address(street: String, city: String)

Ignore the case keyword for the moment. This is level 4. For all Java people, this code can be put in one file, although it is not recommended practice. I just do it here for simplicity. Property is the abstract base class. It defines a field value as all property needs to have a value. House, Car and Horse inherit from Property and add additional information. Address will be used in a later example.

For a special calculation the value will be applied based on the type of property. Houses will be applied with 80% of their value, Horses with 50% and the value of Cars will not be applied at all. Using Pattern Matching this looks like this:

  def applyPropertyValue(property:Property):BigDecimal = property match {
    case house:House => house.value * 0.8
    case horse:Horse => horse.value * 0.5
    case car:Car => 0
    case _ => property.value
  }

Without any instanceof or casting the value has been calculated based on the type of property. Here is a wildcard pattern used in the last line again. If there is another type of property the full value will be applied.

Level 4 – Constructor patterns and Case Classes
The last example already used case classes even if it would have worked with normal classes too. Case classes have some special characteristics.

  • There is a special factory method that allows the class to be instantiated without the new keyword. Car(150,20000) creates a Car object with 150 horsepower and a value of 20.000.
  • All parameters in the constructor are automatically defined as val. So they are fields and can be accessed from other objects.
  • The compiler generates meaningful implementations of equals, hashcode and toString.
  • And of course they can be used in constructor patterns.

In our example we need some very special cases to calculate the value. If a house is in Berlin 90% instead of 80% of the value can be applied. Cars with a horsepower of more than 150 can be applied with 50% of their value instead of 0. Our function now gets two more lines:

  def applyPropertyValue(property:Property):BigDecimal = property match {
    case House(Address(_,"Berlin"),value) => value * 0.9 //Deep match
    case Car(horsepower, value) if horsepower > 150 => value * 0.5 //Pattern Guard
    case house:House => house.value * 0.8
    case horse:Horse => horse.value * 0.5
    case car:Car => 0
    case _ => property.value
  }

The more special a case is the earlier it has to be validated. If the general case for Car would be matched first, the more specialized pattern would never be validated. In simple cases the Scala compiler complains about the code being unreachable.
The two new lines use the constructor pattern, that is only possible for case classes. But both also demonstrate other features of Pattern Matching. The House pattern shows a nested pattern. The important condition is in class Address, which is nested inside House. This kind of deep matches can save a lot of code. Imagine how many if statements, casts and instanceofs this needs in Java. The Car example shows another syntax for pattern matching. It is called Pattern Guards. An additional if after the pattern allows to validate conditions, before the pattern code will be excecuted.

Level 5 and above
This is still not all that can be learned about Pattern Matching. The story goes on with sequence patterns, sealed classes, partial functions and much more. But by now you should be able to understand most Pattern Matching statements that can be found in Scala. For more details I can only recommend reading Programming in Scala. It contains a lot of fun stuff like that.

Five random lessons learned about Scala

Posted in java, scala, software development on April 15th, 2009 by Joerg – 7 Comments

Since a week I am playing around with Scala to see what all this fuss is about. After Twitter has anounced that they are using Scala (see this presentation) there is a real hype now. So far I must admit I am impressed. This language is really nice. I will certainly have a very detailed look. The book “Programming in Scala” is already on its way from Amazon.

The following lessons learned are just a kind of note to self. These are some random experiences I made when playing around. Your first lessons will probably be completely different.

1. Scala != Groovy
Although this is obvious, when you have prior experience in Groovy it is tempting to fall into your Groovy habits. Both languages look similar at a glance but are very different in detail. For instance I very often write def when defining a variable where it should be val or var. The fact that def is a valid keyword in Scala and is used to define methods is not helpful in this regard. There are so many other subtile differences that I can’t mention them here. Just be aware of that.

2. Use a decompiler
A decompiler can be very useful when learning Scala. Just compile the Scala class and then decompile it. This way you can easily see, what the Scala compiler is creating when using certain language features. I discovered a nice decompiler while doing this. It can be found here. The decompiler was key for solving the next issue.

3. Be careful with field level annotations
It is a great feature of Scala that you can use established Java frameworks and just replace the Java code with Scala. This way you can easily use Spring and the likes. I did that but had sudden problems with the Spring @Autowired annotation. I annotated the field like that:

@Autowired
var pollService: IPollService = _;

Spring was starting to complain about missing parameters on the annotated method. What?
Ok, I was aware that Scala generates corresponding methods for a field just like Groovy does. But what was the issue here? The Spring annotation is defined as field level and method level annotation. But when it is used on a method it has to be a setter which gets at least one parameter. The decompiler saved the day. It shows that Scala is applying the annotation three times. At the field, at the setter pollService_$eq() and the getter pollService(). The last causes the Spring exception. (For all Scala experts, the @BeanProperty annotation does not solve the problem)
The (ugly) workaround is to create the setter manually and annotate only this. Here is how:

var pollService: IPollService = _;

@Autowired
def setPollService(pollService: IPollService) = {this.pollService = pollService}

4. Switch of “Compile Scala files first” in IDEA

There is a small bug/inconvinience in the current Scala plugin of IntelliJ Idea. It occurs when you have a project with combined Java and Scala sources. Any Java class that is located in a test source folder will not compile. You will get an error message “ClassX is already defined as class ClassX”. To fix this you can simply change the Scala compiler settings. Go to Settings->Compiler->Scala and uncheck “Compile Scala Files First”. It is not perfect, as you might need to manually (Ctrl-Shift-F9) compile Scala sources that Java files depend on. But at least you can compile everything now.

5. Use Scalatest!
If you want to write tests in Scala try Scalatest. It shows perfectly what can be done in Scala. It enables different styles of testing like xUnit or BDD just by applying different traits. And it enables you to use TestNG in your Scala tests. This way you can just start tests in Scala as if they where Java, at least in Intellij Idea. Here is a small example how a Test can look like:

@Test def testCreateTopicPoll() = {
  val pollDto = preparePoll
  val pollId = pollService saveOrUpdateTopicPoll pollDto;
  pollId should not be null
}

Look at the last line. Isn’t that beautiful? This is real code. You would not need any comments to explain, what is under test here.

I can strongly recommend that you have a look into Scala. It is a very interesting language with some nice concepts. I hope that some of my lessons learned help you when doing your first steps. Then let me know what lessons you learned!

Inheritance of class annotations in TestNG

Posted in java, software development, testing on April 5th, 2009 by Joerg – 1 Comment

Recently Oliver Fischer introduced TestNG at the Berlin-Brandenburg JUG. At one point there was an interesting discussion with the audience about class level annotations. Why should they be used? You can annotate a class like this:

@Test
public class Foo 
{
...

Now every public method in this class is considered a test method. Several people in the audience mentioned that they would still prefer to mark the test explicitly. This is just more readable. But if so, what might be a good reason to use class level annotations?

One very nice characteristic of class level annotations is that they can be inherited. Let’s assume you want several classes in a specific testgroup. What you don’t want to do is to annotate each and every test method with @Test(groups = {“MyTestGroup”}). This is simply not DRY. Using inheritance, you can instead create a base-class like this:

@Test(groups = {"MyTestGroup"})
public class BaseClass 
{
...

Now each test class that should be in this group can just extend BaseClass.

public class MyTestClass extends BaseClass 
{
...

Every public method in these classes is a test method and they belong to the group MyTestGroup. You probably still want to add the @Test annotation to each of the methods for readability. The group assignment is still valid.

What other ideas do you have for making use of annotation inheritance in TestNG?

Super simple method to create a boolean decision table

Posted in software development, testing on March 27th, 2009 by Joerg – 3 Comments

Today one of our test engineers, Manfred, presented about systematic identification of test values. One of the topics were decision tables. I was fascinated how easy he created tables with all possible combinations. Here is how:

    1. Write the conditions in seperate rows.
Condition A 
Condition B
Condition C
    1. Now make 2^n columns where n is the number of conditions.
Condition A |   |   |   |   |   |   |   |   |
Condition B |   |   |   |   |   |   |   |   |
Condition C |   |   |   |   |   |   |   |   |
    1. Start at the bottom condition and write alternating Y and N.
Condition A |   |   |   |   |   |   |   |   |
Condition B |   |   |   |   |   |   |   |   |
Condition C | Y | N | Y | N | Y | N | Y | N |
    1. Fill the next row with alternating Y Y N N …
Condition A |   |   |   |   |   |   |   |   |
Condition B | Y | Y | N | N | Y | Y | N | N |
Condition C | Y | N | Y | N | Y | N | Y | N |
    1. Each row you double the number of consecutive Ys and Ns.
Condition A | Y | Y | Y | Y | N | N | N | N |
Condition B | Y | Y | N | N | Y | Y | N | N |
Condition C | Y | N | Y | N | Y | N | Y | N |
    1. Do so until all rows are filled.
    2. Now you can add your decisions to the table.
Condition A | Y | Y | Y | Y | N | N | N | N |
Condition B | Y | Y | N | N | Y | Y | N | N |
Condition C | Y | N | Y | N | Y | N | Y | N |
---------------------------------------------
Decision 1  |   | X | X |   |   |   |   |   |
...

Using this algorithm you can be sure you covered all combinations. It doesn’t matter how many conditions you have and you don’t even have to think 🙂

Thanks Manfred!

Tomahawk and Spring Webflow

Posted in java, software development on March 20th, 2009 by Joerg – Be the first to comment

I recently ran into a configuration problem when using Apache Tomahawk and Spring Webflow together. When using some of the more advanced components like <t:inputDate> I got an error message:

...
java.lang.IllegalStateException: ExtensionsFilter not correctly configured. JSF mapping missing.
...

I did configure the MyFacesExtensionsFilter like shown in the documentation but that was not enough:

 <filter>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
     ...
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
  </filter-mapping>

After some debugging it turned out that this filter was never called. The solution is simple. When you combine Spring Webflow and JSF the Faces Servlet has no real function. It just needs to be there for some compatibility reasons. The real servlet that needs to be filtered is the Spring MVC Dispatcher Servlet. So you need to change the filter mapping like this:

<filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
</filter-mapping>

This also applies for all other filters that are usually applied to the faces servlet, like the Trinidad filter.