Tuesday, September 29, 2009

This topic continues the previous topic on matching and Extractors. Make sure you look at Extractors 1.

The first extractor topic covered the unapply method and how it is used during matching. Today I want to visit a similar method unapplySeq, which is used to match sequences. The method defunapplySeq(param):Option[Seq[T] can be used instead of unapply.

Note: if both unapply and unapplySeq are defined only unapply is used.

When matching on Sequences the _* symbol means to match an arbitrary sequence. We use this several times in the examples below

scala>object FindAs {

| defunapplySeq(string:String):Option[List[String]] = {

| def containsA (word:String) = word.toLowerCase contains "a"

|

| if (string.toLowerCase contains "a") {

| val words = string.split ("\\s+").

| filter (containsA _)

| Some(words.toList)

| } else {

| None

| }

| }

| }

defined module FindAs

// as usual you can use extractors to assign variables

scala>val FindAs(a,b) = "This sentence contains 2 a-s"

a: String = contains

b: String = a-s

// If you only care about the first variable you can use _* to

// reference the rest of the sequence that you don-t care about

scala>val FindAs(a, _*) = "A crazy a sentence ack!"

a: String = A

// using b @ _* we can get the rest of the sequence assigned to b

scala>val FindAs(a, b@_*) = "A crazy a sentence ack!"

a: String = A

b: Seq[String] = List(crazy, a, ack!)

// standard matching pattern

scala>"This sentence contains 2 a-s"match {

| case FindAs(a,b) => println(a,b)

| case _ => println("whoops")

| }

(contains,a-s)

// In this example we only care that it can match not the values

// so we ignore all of the actual sequence by using: _* as the parameters

Monday, September 28, 2009

When defining a match such as case Tuple2(one, two) the methods Tuple2.unapply and Tuple2.unapplySeq are called to see if that case can match the input. If one of methods return a Some(...) object then the case is considered to be a match. These methods are called Extractor methods because they essentially decompose the object into several parameters.

I will cover unapplySeq later.

Examples are the best way to illustrate the issue:

// The unapply method of this object takes a string and returns an Option[String]

// This means that the value being matched must be a string and the value extracted is also a string

Thursday, September 24, 2009

One possibly surprising rule of matching is that lowercase identifiers in the case clause always have a value bound to them but if the identifier starts with an uppercase character the identifier is used as a value to match against.

scala> val iWantToMatch = 10

iWantToMatch: Int = 10

scala> val iDontWantToMatch = 1

iDontWantToMatch: Int = 1

scala> 10 match {

| case iDontWantToMatch => "boo"

| case iWantToMatch => "yay"

| }

:7: error: unreachable code

case iWantToMatch => "yay"

^

// we have an error because iDontWantToMatch is treated as a parameter to the iDontWantToMatch => "boo" function.

// Not as a value to match against.

// in this example you can see how iDontWantToMatch is has 10 bound to it

Wednesday, September 23, 2009

In Java-land many frameworks depend on Bean style properties. Scala has an extremely handy annotation that assists in interoperating with frameworks that require bean-style interfaces. In Scala 2.7 there are only a few annotations for helping:

@BeanProperty - Generates getters and setters for a property. (Or just a getter if the bean is a val)

@BeanInfo - Generates the associated BeanInfo for the class

Remember that if you want frameworks to be able to create the beans you need to make a 0-arg constructor and have the bean properties as fields.

Example with bean-properties as constructor arguments. This example requires Scala 2.8 because it uses BooleanBeanProperty. You can remove that and run with Scala 2.7.x.In this example we define a bean class and use reflection to show that all the getters and setters are generated:

scala> import scala.reflect._

import scala.reflect._

scala> caseclass MyBean(

| @BeanPropertyvar mutable:String, // getter and setter should be generated

| @BooleanBeanPropertyvar boolProp:Boolean, // is getter and normal setter should be generated

Tuesday, September 22, 2009

Todays topic does not introduce anything new, it just a useful example of using a function to create a list of objects. This is NOT part of the standard library.

The methods are called unfoldRight and unfoldLeft because they are more or less the inverse of foldLeft and foldRight. foldLeft and Right run a function on each element in a list producing some result. unfoldLeft and right produce a list from a function and a seed value. The List is created from executing the function repeatedly with the result from the previous execution (or the seed value). Each function call returns a result which is the element in the list. The list is done when the function returns None rather than Some(x).

This sample is directly derived from the samples: http://paste.pocoo.org/show/140865/

Remember the performance differences between the two. Adding an element to the head of scala list is a constant operation but adding an element to the end(tail) of the list is linear time based on the size of the list. So unfoldLeft will typically suffer from worse performance.

Friday, September 18, 2009

One nice feature built into Scala are "lazy val" values. Essentially they are the lazy initialization pattern that is very commonly implemented in Java programs (and very commonly incorrectly implemented). When a val is declared with the lazy modifier the right-hand side of the value (the definition) will not be executed until the first time the value is accessed.

A related forth coming topic is the topic on lazy collections and projections and streams. They are all ways to lazily evaluate collections.

Note: The code for today must be put in a file and executed. Lazy val's cannot be demonstrated in the REPL because after each value is declared in a REPL the variable is accessed and it is printed out in the next line. If I considered it important enough I could have defined a method in the REPL, put the code in the method and then called the method and demonstrated it and if you wish feel free to do that. But I recommend creating a file and running scala yourfile

Examples:

val normalVal = {

println("---->>> Initializing normal val <<);

"This is the normal val"

}

lazy val lazyVal = {

println("---->>> Initializing lazy val <<);

"This is the lazy val"

}

println ("\n\nno references have been made yet\n\n")

println ("Accessing normal val : ")

println(normalVal)

println ("\n\nAccessing lazy val : ")

println(lazyVal)

println ("\n\nAccessing lazy val a second time, there should be no initialization now: ")

Thursday, September 17, 2009

Defined in the Predef object are several implicit methods. All implicit methods defined in the Predef method are applicable to all programs without importing them. One such method is the -> method. This method is applicable to all objects and creates a Tuple2.

Wednesday, September 16, 2009

The Regex class in Scala provides a very handy feature that allows you to match against regular expressions. This makes dealing with certain types of regular expression very clean and easy to follow.

What needs to be done is to create a Regex class and assign it to a val. It is recommended that the val starts with an Uppercase letter, see the topic of matching about the assumptions matching makes based on the first letter of the Match case clause.

There is nothing like examples to help explain an idea:

// I normally use raw strings (""") for regular expressions so that I don't have to escape all \ characters

// There are two ways to create Regex objects.

// 1. Use the RichString's r method

// 2. Create it using the normal Regex constructor

scala> val Name = """(\w+)\s+(\w+)""".r

Name: scala.util.matching.Regex = (\w+)\s+(\w+)

scala> import scala.util.matching._

import scala.util.matching._

// Notice the val name starts with an upper case letter

scala> val Name = new Regex("""(\w+)\s+(\w+)""")

Name: scala.util.matching.Regex = (\w+)\s+(\w+)

scala> "Jesse Eichar"match {

| case Name(first,last) => println("found: ", first, last)

| case _ => println("oh no!")

| }

(found: ,Jesse,Eichar)

scala> val FullName = """(\w+)\s+(\w+)\s+(\w+)""".r

FullName: scala.util.matching.Regex = (\w+)\s+(\w+)\s+(\w+)

// If you KNOW that the match will work you can assign it to a variable

// Only do this if you are sure the match will work otherwise you will get a MatchError

Monday, September 14, 2009

In the spirit of making Scala scalable from scripts up to systems, Scala contains some syntactic sugar to make scripting and internal DSLs a bit easier to write. For example there are several situations where the '.' and '()' for method calls are optional. Semi-colons are optional (except for single-line statements).

There are some corner cases but the basic rule is that you need an odd number of arguments if you wish leave out the '.'.Examples:

scala> "hello" substring (1,3)

res0: java.lang.String = el

scala> "hello" substring 1

res1: java.lang.String = ello

scala> 1 toString ()

res2: java.lang.String = 1

Precendence runs left to right so:

"hello" contains "hello world" toString ()

becomes

"hello".contains("hello world").toString()

Another example:

scala> "hello" contains "hello world" toString () substring 4

res6: java.lang.String = e

scala> "hello".contains("hello world").toString().substring(4)

res7: java.lang.String = e

There is some operator precendence which we will cover later. Operator precedence allows statements like the following:

One of the most common uses of a companion object (See Companion Objects for more) is as a factory for creating instances of the class. For example, there may be several overloaded apply methods which provide different ways of instantiating the object. This is often preferred to adding many constructors because Scala places restrictions on constructors that Java does not have.

One built in example of Factory methods in a companion object are when you create a case class.

Friday, September 11, 2009

Just an interesting tidbit you may not know. Scala is also available on the .Net platform. Although to be sure it is not as complete as the Java version. But the point is that there is an additional value add to learning Scala.

Thursday, September 10, 2009

Assignment in Scala follows more or less the same rules as Java and other related rules. There are some differences.

Increment operators do not work (i++). As I understand it the rational is that it is too specific an idiom. There is not an easy way to generalize it. Instead you must use i += 1.

Assignments do not return a value. For example you cannot do val i = j = 2 or while( (i = read(buffer)) > 0 ){...}.

One feature that is fairly unique in Scala is the ability to expand a case-class or other class that has an associated extractor. For details look at the previous topic Assignment and Parameter Objects.

Wednesday, September 9, 2009

Today's topic is based on an article by Bill Venners. http://www.artima.com/scalazine/articles/selfless_trait_pattern.html. I recommend reading that article as it goes into much more detail. I also recommend taking a look at the earlier topic that covers companion objects.

The normal way to use a trait is to mix it in to an object. However there can be a problem mixing two traits containing methods with equal signatures. If the two traits are not designed to work together then you will get a compile error. Otherwise one method will override the other. Either way you cannot access both methods. There is an additional way to access the functionality of a trait. You can create an object (not instance) that extends the trait and import the methods when you need them.

If the trait is stateless then the object can be shared if not then make sure that sharing the object is carefully handled.

Examples:

scala> trait T1 {

| def talk = "hi"

| }

defined trait T1

scala> trait T2 {

| def talk = "hello"

| }

defined trait T2

// Cannot extend C with T1 and T2 because they are not designed to work together

A companion object is an object with the same name as a class or trait and is defined in the same source file as the associated file or trait. A companion object differs from other objects as it has access rights to the class/trait that other objects do not. In particular it can access methods and fields that are private in the class/trait.

An analog to a companion object in Java is having a class with static methods. In Scala you would move the static methods to a Companion object.

One of the most common uses of a companion object is to define factory methods for class. An example is case-classes. When a case-class is declared a companion object is created for the case-class with a factory method that has the same signature as the primary constructor of the case class. That is why one can create a case-class like: MyCaseClass(param1, param2). No new element is required for case-class instantiation.

A second common use-case for companion objects is to create extractors for the class. I will mention extractors in a future topic. Basically extractors allow matching to work with arbitrary classes.

NOTE: Because the companion object and the class must be defined in the same source file you cannot create them in the interpreter. So copy the following example into a file and run it in script mode:

Tuesday, September 8, 2009

Folding and reducing are two types of operations that are both very important with dealing with collections in Scala (and other functional languages). This topic covers the fold operations. The reduce topic was previously covered.

A simplistic explanation is they allow processing of the collections. I think about foldRight and foldLeft to be very similar to a visitor that visits each element and performs a calculation. It does not change the values of the collection instead it calculates a result from visiting each element. In Java you might see the following pattern:

class Collection {

pubic Result op( Result startingValue, Op operation){...}

}

interface Op{

public Result op( Object nextCollectionElem, Result lastCalculatedResult)

}

To a Java programmer this is pretty obvious how you use it. This is essentially the fold operation. The difference is we are using closures so there is almost no boilerplate and all collection/Iteratore/Iterable interfaces have the fold methods.

One last point before examples. For fold and reduce operations there are both foldLeft and foldRight and similarly reduceLeft and reduceRight. These indicate the order that a collection is processed. Note that for certain collections one direction is more performant that the other. Lists, for example, are better to process left to right because of the datastructure used.

Some tasks that are suited to fold are:

Find the 5 smallest elements in a list

Sum all the values of a Map together

Sum the lengths of the Strings contained in the collection

There are a number of ways that fold can be written syntactically. The following examples are ways to sum together the integers of a Map. Note that /: is an alias for foldLeft and :/ is an alias for foldRight. Normally foldLeft and foldRight should be used unless the rest of the developers who will be reading the code are quite confortable reading Scala.

Monday, September 7, 2009

Folding and reducing are two types of operations that are both very important when dealing with collections in Scala (and other functional languages). This topic covers the reduce operations. The fold topic will be covered shortly.

A simplistic (probably over-simplistic) explanation is they allow processing of the collections. One can consider foldRight and foldLeft to be very similar to a visitor that visits each element and performs a calculation. It does not change the values of the collection, instead it calculates a result from visiting each element. In Java you might see the following pattern:

class Collection {

pubic Result op( Result startingValue, Op operation){...}

}

interface Op{

public Result op( Object nextCollectionElem, Result lastCalculatedResult)

}

To a Java programmer this is pretty obvious how you use it. Reduce operations are similar but very narrow in scope. They only return values that are of the same type as the original collection (IE a list of Int will return an Int from reduce) and there is no initial seed value. The first two inputs are the first and second elements of the collection. If there is only one element then that element is returned.

Reduce might look like the following in Java:

class Collection {

pubic Integer op(Op operation){...}

}

interface Op{

public Integer op( Integer nextElem, Int lastCalculatedResult)

}

One last point before examples. For fold and reduce operations there are both foldLeft and foldRight and similarly reduceLeft and reduceRight. These indicate the order that a collection is processed. Note that for certain collections one direction is more performant that the other. Lists, for example, are better to process left to right because of the datastructure used.

Thursday, September 3, 2009

In Scala exceptions are not checked so effectively all exceptions are runtime exceptions. When you want to handle exceptions you use a try {...} catch {...} block like you would in Java except that the catch block uses matching to identify and handle the exceptions. This creates a very powerful but light-weight way to handle exceptions:

One useful application of a trait is the case where you want to add functionality to an existing class. In this example I have a class provided by a third party library (in this just a simple StringReader class from the Java library). But I want to be able to read lines as well as use the standard read methods.

One solution is to create a trait and when I instantiate the StringReader mix in the new trait. Code like new StringReader() with Lines results in a new class that extends StringReader and the trait Lines. As a result we have all the methods of StringReader and Lines. The biggest benefit is that we can define the trait to work with any Reader and then when we create the real instance we can mix it in to any class that extends Reader.

The other solution that can be used is to create an implicit conversion from StringReader to some other class. There are two draw backs here:

It is harder to tell what is happening

A trait can contain state but a "view" (which is what you get when one class is implicitly converted to another class) has no state it is just a view of the original class. In this example a view would work but in other examples like creating a pushback reader, it would not work.

Here is a simple example:

scala>trait Lines {

| // the self type declares what type of class the trait can be applied to

| // if there is no self type then it is assumed it can be applied to Any type

| self:java.io.Reader =>

| def nextLine:Option[String] = {

| val builder = new scala.collection.mutable.StringBuilder()

|

| var next = read()

|

| while( next != -1 && next.toByte.toChar != '\n' ){

| builder += next.toByte.toChar

| next = read()

| }

|

| if( builder.isEmpty ) None

| else Some(builder.toString)

| }

| }

defined trait Lines

// Strings starting and ending with (""") are called raw strings. All characters

// within """ """ are automatically escaped.

// I am creating a reader and mixing in the Lines trait on construction

Tuesday, September 1, 2009

One of the refactorings I find myself doing quite often in Scala is converting large branching if trees into an easy to read match statement. The reasoning is that it is much easier to read a match statement because it is like reading bullet points rather than trying to follow the flow of information through a tree of if statements.

Before you complain, I realize there are other ways to refactor a tree of if-statements but I find the match statements the easiest to reason about and the quickest to write with the least amount of boiler plate.

Here is an example where I need to see if the file is dirty and needs to be regenerated, if it is clean or if some one has modified the generated file (which results in a CONFLICT).

Search This Blog

About Me

Jesse EicharI am a senior software developer at Camptocamp SA (Swiss office) and specialize in open-source geospatial Java projects. I am a member of the uDig steering committee and a contributor to Geotools and Mapfish. In addition I regularly work with Geoserver and Geonetwork.

In my free time I am a Scala enthusiast. I am working on the Scala IO incubator project and WebSpecs a Specs2 based testing framework for webapplications.