Pages

27 July 2008

My first ICFP contest, Part 2: parser combinators are so cool

This is the sequel to my last post on participating to the ICFP contest 2008.

The Setup

As Curt wrote it, we entered the contest doing things that should have been done well before:
  • setting up the wifi access so that I can connect with my laptop (it never worked so Bryan had to get out and buy new network cables)
  • exchanging keys to access the Subversion repository
  • learning how to use the build and test system
I guess that we need to make some mistakes (at least) once oneself before getting it!

However, the biggest lesson for me in this contest, was the use of Parser Combinators.

Do you speak Martian?

The second programming task in the contest, after setting up the network connection to be able to receive messages and send back commands, was to parse the input messages giving the position of the Martian rover, and its immediate environment.

As the task specifies, there are 5 kinds of messages:
  • initialization messages -> what's the map like? what are you technical constants?
  • telemetry stream -> where are you, what's your speed, what's around?
  • adverse event -> crashed in a crater!
  • success -> yes, home!
  • end of run -> time and status
The format of those messages is not particularly complex but the telemetry message can contain an unlimited number of obstacles descriptions for example.

For many developers, the most obvious way to transforms meaningless strings to meaningful objects like Telemetry or Martian, would be to start traversing the string, check for characters like 'T' for Telemetry, or 'I' for Initialization then pass the rest of the string to another function and continue slicing the string until all data is analyzed.

Parser combinators

But Haskell developers know better,... They can just describe the grammar of the messages they're parsing by combining parsers, then applying the resulting parser to the string input.

Something like that:

telemetry :: Parser Message
telemetry = do ts <- int
state <- accelStateParser
turning <- turningStateParser
spaces
x <- double
y <- double
dir <- double
speed <- double
obstacles <- obstaclesParser
messageEnd
return $ Telemetry ts state turning x y dir speed obstacles

accelStateParser :: Parser AccelState
accelStateParser = (accelerating <|> braking <|> rolling)

accelerating = stateParser 'a' Accelerating
braking = stateParser 'b' Braking
rolling = stateParser '-' Rolling

stateParser :: Char -> a -> Parser a
stateParser c cons = do _ <- char c
return cons

turningStateParser :: Parser TurningState
turningStateParser = hardleft <|> softleft
<|> hardright <|> softright
<|> straight

hardleft = stateParser 'L' HardLeft
softleft = stateParser 'l' SoftLeft
hardright = stateParser 'R' HardRight
softright = stateParser 'r' SoftRight
straight = stateParser '-' Straight
obstaclesParser :: Parser [Object]
obstaclesParser = do l <- many obstacleParser
return l

obstacleParser :: Parser Object
obstacleParser = do code <- oneOf "bchm"
spaces
case code of
'b' -> object Boulder
'c' -> object Crater
'h' -> object Home
'm' -> martian
_ -> error "Can't get here in parser!"

object :: (Circle -> a) -> Parser a
object cons = do x <- double
y <- double
r <- double
spaces
return $ cons (Circle (x:.y) r)

martian :: Parser Object
martian = do x <- double
y <- double
dir <- double
speed <- double
spaces
return $ Martian (Circle (x:.y) 0.4) dir speed

In the above code, you can read that the parser for telemetry messages is a sequence of different parsers: a timestamp parser, a acceleration state parser, a turning state parser, ..., a parser for lists of obstacles. And a parser for list of obstacles is just "many" parsers for one obstacle. This is indeed as easy as being able to describe a grammar for that mini-language.

"k" should better be 1

But I didn't say that describing a grammar was easy! For instance, at first, we made a mistake in the way we managed spaces. We had almost each parser trying to consume spaces before doing its job. This generated unnecessary ambiguity in the parsing.

For example, let's say that you want to be able to parse this kind of message:

" O T O O T"

(honestly, I don't know why you would like to do something like that but you're the boss here)

You'd better combine those 3 parsers:
  • spaces -> will consume any number of spaces

  • oneParser = char 'O' >>= spaces -> will consume 'O' followed by any number of spaces

  • twoParser = char 'T' >>= spaces -> will consume 'T' followed by any number of spaces

If you define parsers differently, having "oneParser" and "twoParser" consuming spaces before they parse their character, which parser should be used on the first space of the message?

Actually, parser combinators in Haskell are also capable of backtracking and "unparsing" results if the chosen parser was not appropriate (trying things with the the "try" parser combinator). But why add more complexity when things can be described more directly?

Of course, there is a formal theory behind the example above: LL(k) grammars, where LL(1) is a type of grammar only needing to look at the next character to know which parser to use. But there's nothing like a simple "real-life" example to be able to grasp it.

Compare and contrast

Now, honestly, most other contest solutions were not using Parser combinators and the aren't soooo ugly (in Dylan for example). I think they're just less readable and more error-prone because of index manipulation.

For fun and comparison, I also developed a similar parser in Scala:

def telemetryMessage = for { timestamp <- intNumber
accState <- accelState
turnState <- turningState
vehicleX <- doubleNumber
vehicleY <- doubleNumber
vehicleDir <- doubleNumber
vehicleSpeed <- doubleNumber
obstacles <- objects }
yield Telemetry(timestamp, accState(), turnState(),
vehicleX, vehicleY, vehicleDir,
vehicleSpeed, obstacles)

def accelState = (
"a" ^^^ Accelerating
| "b" ^^^ Braking
| "-" ^^^ Rolling
)

def turningState = (
"l" ^^^ SoftLeft
| "L" ^^^ HardLeft
| "-" ^^^ Straight
| "r" ^^^ SoftRight
| "R" ^^^ HardRight
)

def objects = rep(objectParser)
def objectParser: Parser[Object] = (
"b" ~ spaces ~> circleParser ^^ (new Boulder(_))
| "c" ~ spaces ~> circleParser ^^ (new Crater(_))
| "h" ~ spaces ~> circleParser ^^ (new Crater(_))
| "m" ~ spaces ~> martianParser
)

def circleParser = for { x <- doubleNumber
y <- doubleNumber
r <- doubleNumber }
yield new Circle(x, y, r)

def martianParser = for { circle <- circleParser
dir <- doubleNumber
speed <- doubleNumber }
yield new Martian(circle, dir, speed)


The interesting things in the Scala implementation, although it could seem a bit ugly at first sight, are:

  • the use of a sequence operator "~>" getting rid of what has already been parsed. Indeed, when we have parsed "b " we know we need to create a Boulder object. The 'b' character and the space are then not usefull anymore

  • the use of functions to transform the parsed string into a meaningful object, like "l" ^^^ SoftLeft, creating a new SoftLeft object (it's a case class) when parsing "l"

  • implicit definitions. In the example above I don't need to declare my parser for 'l' as letter("l"). Combining "l" with another parser automatically creates a parser for the character 'l'

Why XML?

One of the reasons for the ubiquitous adoption (and hate!) of XML is, I think, the general availability of parsers and binding libraries. This is why this often becomes the easiest option for configuration files (is it changing with YAML and JSON?).

It doesn't have to be that way. I hope that parser combinators can now bring another legitimate option when considering the implementation of an external mini-language for configuration or protocol. They're simple to use and readily available on your Java platform through Scala. Try them at home!

08 July 2008

My first ICFP contest, Part 1: ten days to learn Haskell

I wanted to do that since I read Tom's Moertel post on his participation to the ICFP contest 2001. I Told my wife: "One day, I'll participate to the ICFP contest" (head slightly tilted up with a brilliant and determined look in the eyes).

One day, I'll participate to the ICFP contest

Fortunately, that day came quick as I met, last month, other geeks in Tokyo ready to get into the race. I should say über-geeks when I realize the gaps I have in my knowledge of some fields of computing compared to them. System and network programming being only the emerged part of the iceberg.

I met them for the first time during the monthly meeting of the Tokyo Society for the Application of Currying (try to explain that to your grandma). That night we decided that we would form a team for the next ICFP contest. Then, we spent the next week discussing the team name, that was the difficult decision. The easy one was the language we would use. What is THE language of choice for functional hackers? Haskell of course! [flaming starts here]

But how do you learn Haskell in 10 days and hope to be able to contribute at least a little?

Learn Haskell in 10 days!

Actually, I've reading about Haskell for a while now, starting with the very enjoyable A History of Haskell: Being LazyWith Class. From there and working with Scala for the past year, I had understood the following:
  • the "functional" approach vs the "sequential" approach
  • immutable data structures
  • functions as first-class objects
  • lazy evaluation
  • thinking in types
  • thinking in higher-ranked types
  • Options / Maybe
  • List operations: map, folds,...
  • pattern matching
  • type classes / traits
This makes an impressive list of language features but I must say that Scala is a really "transitional language" for Java programmers towards Haskell. Riiiight. I "understand" it but how well can I program within 10 days?

The laundry list

Using a programming language always involves a wealth of down-to-earth considerations worth getting right as fast as possible. Here is my list and how I organized my environment:
  1. the compiler: I used GHC and the Hugs interpreter for Windows
  2. the editor: I used the Functional plugin for eclipse, providing editing, compilation, creation of an executable
  3. the librairies: I downloaded / compiled and installed QuickCheck2 and otherwise used the bundled libraries with GHC
  4. code coverage: hcp (not really indispensable for a beginning but a nice to have for a non-strict language. I was happy to eventually get it to work)
This is clearly non-optimal yet (and I wonder if it can be on Windows?) and I'll certainly explore:
  1. a better editor: considering what can be done in Java, it's pretty amazing that there is no high-class editor for Haskell. I'll try Yi of course, but it's still in its infancy. "Rename function" or "Rename data type" should be pretty accessible (provided enough open-source or company support, that is,...)
  2. a build/test/continuous integration system. The guys from Starling Software have their own system for that matter (QAM) and I haven't seen yet such a standard thing for Haskell.
  3. more libraries, libraries management: I still haven't done it on windows but I plan to install Cabal and download the whole Hackage.
  4. Switching to linux forever. I'll certainly cover this in part 2 but Windows seems less and less a decent alternative for hackers (I didn't say developers ;-) ).
Yes, all set-up! I can start my first tutorial!

No, I'd rather do a code dojo first

Why bother using a tutorial when I have a nice little programming exercise at hand? I did it in Java, I did it in Ruby, I did it in Scala, it was time to use Haskell.

Basically the question is: write a program to transform Roman number back and forth to Integers: unromanize("MCMLXXII") == 1972.

Here is my solution with Haskell:

-- SOME VALUES DECLARATION
-- definition of the roman letters with their numerical value
romansList = [("I", 1), ("IV",4), ("V", 5), ("IX", 9), ("X", 10), ("XL", 40),
("L", 50), ("XC", 100), ("C", 100), ("CD", 400), ("D", 500),
("CM", 900), ("M", 1000)]
-- numerical values only
values = map snd romansList
-- letters only
letters = map fst romansList

-- return the value corresponding to a letter
value :: String -> Int
value c = findWithDefault 1 c (fromList romansList)

-- return the letter corresponding to a value
letter :: Int -> String
letter i = findWithDefault "I" i reversed
where reversed = fromList(map switch romansList)
switch = (\(x, y) -> (y, x))

-- to get the value of a RomanString, start
-- from the end and accumulate the value of each letter
-- substract the value of the current letter if its value is
-- inferior to the previous one
-- ex: "XIV" -> 5 (for "V") - 1 (for "I") + 10 (for "X")
unromanize :: String -> Int
unromanize s = fst(foldr add (0, 0) s)

add :: Char -> (Int, Int) -> (Int, Int)
add c (total, lastElem) =
if (lastElem <= val) then (total + val, val)
else (total - val, val)
where val = value [c]
-- [c] is the Char 'c' as a String

-- return the RomanString corresponding to an Int value
-- start with an empty string and the value to convert
-- use the romanizeString function to compute the RomanString

romanize :: Int -> String
romanize i = fst $ romanizeString ("", i)

-- if the remainder is 0, there is no more conversion to do
-- otherwise, try to substract the biggest possible RomanChar from the remainder
-- this RomanChar is then appended to the current result
romanizeString :: (String, Int) -> (String, Int)
romanizeString result@(res, remain) =
if (remain == 0) then result
else romanizeString(res ++ (letter maxi), remain - maxi)
where maxi = maxValue remain
maxValue r = last (takeWhile (<= r) values)


And here is a simple QuickCheck properties that I wrote to check the conversion:
prop_unromanize_romanize :: Int -> Property
prop_unromanize_romanize x = x >= 0 ==> unromanize(romanize x) == x

First impressions

Working on that simple example (but also on string generators to check the reverse property romanize(unromanize) -- much more tricky) led me to the following observations:
  • programming in Haskell really "feels" pure and elegant. There is an economy of symbols which is quite remarkable for such an expressivity
  • not having variables feels like programming in a straight jacket when coming from an imperative background! But the feeling disappears quickly
  • the "functional/data" orientation makes a whole different mental model when you come from an object-oriented perspective. It looks like your objects, encapsulating their data and showing only their business logic have been turned inside out and methods carefully separated from data.
  • browsing the libraries feels like there a huge drive towards abstraction in Haskell. Nowhere else I've seen concepts decomposed so that Monoids would emerge and be reused
  • new language, new librairies. It really takes time but Haskell libraries are full of jewels which are really worth knowing inside out (the same can certainly be said from many languages)
  • although the Prelude contains a lot of useful functions, some facilities you may find in scripting languages are missing. We recently discussed the lack of a "split" operation for Strings on the Haskell mailing-list recently. I know that different people have different semantics for a "split" operation but not including any kind in the standard library feels like it's missing something
  • the compiler is your friend! It goes at great length explaining you why and where you failed to properly type your program
Go, go, go

After those 2 or 3 sessions of installation and programming I was very far from being able to code on my own for the contest, yet I would be able to pair-up and provide a vigilant pair of eyes on someone else code. Stay tuned for part 2: the contest!

03 July 2008

Everyday monads

Abstraction

Abstraction is the bread and butter of our trade, right? The problem is that when you abstract too much, you don't always know where you came from and why.

You see? The sentence above is already very abstract ;-). Let's try to be more concrete. I want to talk about Monads and the kind of problems they solve:


  • monads --> powerful abstract beast
  • problems they solve --> very concrete

A classical code sample

I was trying to fix an issue with our software 2 days ago when I realized that part of my data wasn't valid: "What!? My exposure is not valid, how come!?". A quick look at the code revealed that the validity of an exposure is determined by the following (actually simplified,...):


public boolean isValid() {
return traded && !matured &&
!excluded && !internal && leId > 1;
}

Of course I started blaming the programmer: thank you smart boy, I know that my exposure is not valid but would you have the decency to explain me WHY? Is it untraded and/or matured and/or excluded,...?


I quickly realized why more precise error reporting hadn't been written: time to market. Writing big if/then/else and accumulating error messages is tedious, error-prone and boring to the extreme.


Monads to the rescue!

Somehow, that's the kind of problem that Monads can solve. One way to see Monads is to consider them as a convenient way to chain computations:


  1. you put something in the Monad
  2. you apply one or more functions to it, the results stay in the Monad ("What goes in the Matrix, stays in the Matrix" as I've read somewhere)
  3. then you can extract the final result


Here is the use of a Monad (coded in Scala but you could achieve the same kind of effect in Java) to solve the problem:


def isValid(e: Exposure) = {
e.traded ?~! ("is not traded") ?~! (!e.matured, "is matured") ?~!
(!e.excluded, "is excluded") ?~! (!e.internal, "is internal") ?~!
(e.leId > 1, "doesn't have a defined legal entity")
}
val exposure = new Exposure
exposure.traded = false
exposure.matured = true
isValid(exposure) match {
case f: Failure => {
println(f.messages.mkString("exposure is not valid because: it ", ", it ", ""))
}
}

It outputs:
exposure is not valid because: it is not traded, it is matured, it doesn't have a defined legal entity

So, at the (small) expense of changing the operator from && to ?~! and adding a specific message at each step we get a nice failure message indicating precisely what went wrong.


How does this work?

I implemented this cryptic ?~! operator as a small variation of the existing ?~! method on the Can class from the lift webframework.

A Can is kind of box which either be Empty, Full(of something) or a Failure(reason). So when you perform computations on a Can, either:

  1. there is nothing to do (Empty) --> the result will stay Empty or become a Failure
  2. there is a value (Full(value)) --> the result will either stay Full or become a Failure
  3. it is a Failure --> it will stay a Failure, possibly with an additional error message

What are the 2 operations I need on the Can objects? First of all I need an operation to "put a boolean in the monad". Here I have used an implicit definition:
implicit def returnCan(b: Boolean): Can[Boolean] = if (b) Full(true) else Empty

then I need one method which will either return the same Can if some boolean is true or a new Failure accumulating one more error message:


def ?~!(b: Boolean, msg: String): Can[A] = {
if (b) this else Failure(msg :: this.messages)
}

What happens if the first boolean expression is false?

  1. an Empty Can is created (representing a failure with no cause yet)
  2. the ?~!(msg: String) method is called and returns a Failure(msg)
  3. when the ?~!(b: Boolean, msg: String) method is called, it either returns the same Failure, or create a new one with one more error message

And what happens if the first boolean expression is true?
  1. a Full Can is created (representing a success)
  2. the ?~!(msg: String) method is called and returns the Full can
  3. when the ?~!(b: Boolean, msg: String) method is called, it either returns the same Full can if b is true, or create a new Failure Can with one error message

What I will not do in this post

Although that would be interesting, I will not try to show why the behavior described above actually correspond to a Monad, with the mandatory Monad laws. The first reason is that it is too late to do so ;-). The second reason is that I'm not sure it matters much. What is certainly more important is that Monads, Arrows, Applicative Functors and their kind provide powerful models of computations which can also be applied to Everyday-Enterprisey jobs.

And, by the way, Scala provides syntactic sugar for operators definition, but there is really nothing which avoid us to do the same thing in Java:

// warning!! pseudo-java code!!
class Result {
private List messages = new ArrayList();
private Result(List msgs) {
this.messages = msgs;
}
public Result andCheck(Boolean b, String msg) {
if (b) return this;
else return new Result(messages.append(msg));
}
static public check(Boolean b, String msg) {
return new Result().andCheck(b, msg);
}
}

public Result isValid(e: Exposure) = {
check(e.traded, ("is not traded")).
andCheck(!e.matured, "is matured").
andCheck(!e.excluded, "is excluded").
andCheck(!e.internal, "is internal").
andCheck(e.leId > 1, "doesn't have a defined legal entity")
}


Eureka

I hope I haven't brought more confusion on the topic of Monads with that not-very-formal post. This is a world I'm just starting to explore and I just love when I can have some "Eureka" moments and write better code!

09 June 2008

Edit distance in Scala

How handy.

I was just looking for a way to highlight differences between 2 strings for my Behavior-Driven Development library, specs. And reading the excellent Algorithm Design Manual. Intuitively, I was thinking that there was a better way to show string differences than the one used in jUnit:

Expected kit<t>en but was kit<ch>en
Expected <skate> but was <kite>

The first message shows that <t> has been replaced by <ch>, while the second message says that everything is different! There must be a way to find the minimal set of operations necessary to transform one string to another, right?

The Levenshtein distance

There is indeed. The "Edit" distance, also called "Levenshtein" distance, computes exactly this, the minimal number of insertions, deletions and substitutions required to transform "World" into "Peace" (5, they're very far apart,...).

The computation is usually done by:
  1. examining the first 2 or last 2 letters of each string
  2. assuming the eventual transformation which may occur for those 2 letters:
  • they're equal: "h..." and "h...." --> distance = 0
  • the first one has been removed: "ah..." and "h..." --> distance = 1
  • the second one has been inserted: "h..." and "ah..." --> distance = 1
  • they've been substituted: "ha..." and "ga..." --> distance = 1
  • 3. saying that the final distance is the minimum of the distance when choosing one the
  • 4 possibilities + the distance resulting from the consequences of that choice

  • You can notice that many variations are possible: the distance could be different depending on the letters being added or removed, there could be more allowed operations such as the swapping of 2 letters (distance 1 instead of 2 substitutions of distance 2),...

    Then the final result can either be constructed incrementally or recursively. Incrementally, for "skate" and "kite" you will compute costs from any small prefix to another prefix:
    • "s" to "k" --> distance 1
    • "s" to "ki" --> distance 2

    • "sk" to "ki" --> distance 2
    • "ska" to "kit" --> distance 3
    Then you increase the prefix size and you reuse the distance numbers found for smaller prefixes. The different results can be stored in the following matrix:

    s k a t e

    k 1 1 2 3 4
    i 2 2 2 3 4
    t 3 3 3 2 3
    e 4 4 4 4 2

    Recursively, you do the inverse and you establish that the distance between 2 strings can be computed from knowing the distance between smaller prefixes and you travel the matrix to its upper left corner.

    This is a very good example of Dynamic Programming, where the optimal quantity (the distance at [i, j] in the matrix) you're looking for only depends on:
    • the optimal quantity for a subset of the data (the distance at [i-1, j-1], [i-1, j], [i, j-1])
    • the resulting state (the substrings defined by a position [i-x, j-x] in the matrix)
    • not how you got to that resulting state
    The EditDistance trait

    For the record, I will write here the code I'm using for the implementation, which is constructing the solution incrementally, as opposed to the recursive solution presented on Tony's blog, here.

    The few interesting things to notice about this code are:
    • the algorithm itself ("initializing the matrix"), which is very straightforward
    • the minimum function which is a bit strange because it is not comparing all alternatives. The cost for an insertion is only computed if the cost for a suppression is not better than the cost for a substitution. I would like to work out a formal proof on why this is correct by my intuition tells me that a substitution is generally a "good" operation. It has the same cost as an insertion or a suppression but processes 2 letters at the time. So if we find a better cost using a suppression, it is going to be the best
    • the matrix traversal to retrieve one of the possible paths showing the letters which needs to be transformed for each string: not so fun code with a lot of corner cases
    • the "separators" feature which allows to select the separators of your choice to display the string differences

    trait EditDistance {
    /**
    * Class encapsulating the functions related to the edit distance of 2 strings
    */
    case class EditMatrix(s1: String, s2: String) {
    /* matrix containing the edit distance for any prefix of s1 and s2:
    matrix(i)(j) = edit distance(s1[0..i], s[0..j])*/
    val matrix = new Array[Array[int]](s1.length + 1, s2.length + 1)

    /* initializing the matrix */
    for (i <- 0 to s1.length;
    j <- 0 to s2.length) {
    if (i == 0) matrix(i)(j) = j // j insertions
    else if (j == 0) matrix(i)(j) = i // i suppressions
    else matrix(i)(j) = min(matrix(i - 1)(j) + 1, // suppression
    matrix(i - 1)(j - 1) + (if (s1(i - 1) == s2(j - 1)) 0
    else 1), // substitution
    matrix(i)(j - 1) + 1) // insertion

    }
    /** @return the edit distance between 2 strings */
    def distance = matrix(s1.length)(s2.length)

    /** prints the edit matrix of 2 strings */
    def print = {
    for (i <- 0 to s1.length) {
    def row = for (j <- 0 to s2.length) yield matrix(i)(j)
    println(row.mkString("|"))
    }
    this
    }

    /** @return a (String, String) displaying the differences between each
    input strings. The used separators are parenthesis: '(' and ')'*/
    def showDistance: (String, String) = showDistance("()")

    /**
    * @param sep separators used to hightlight differences. If sep is empty,
    * then no separator is used. If sep contains one character, it is
    * taken as the unique separator. If sep contains 2 or more characters,
    * the first 2 characters are taken as opening separator and closing
    * separator.
    *
    * @return a (String, String) displaying the differences between each
    * input strings. The used separators are specified by the caller.
    */
    def showDistance(sep: String) = {
    val (firstSeparator, secondSeparator) = separators(sep)
    def modify(s: String, c: Char): String = modifyString(s, c.toString)
    def modifyString(s: String, mod: String): String = {
    (firstSeparator + mod + secondSeparator + s).
    removeAll(secondSeparator + firstSeparator)
    }
    def findOperations(dist: Int, i: Int, j:Int, s1mod: String, s2mod: String): (String, String) = {
    if (i == 0 && j == 0) {
    ("", "")
    }
    else if (i == 1 && j == 1) {
    if (dist == 0) (s1(0) + s1mod, s2(0) + s2mod)
    else (modify(s1mod, s1(0)), modify(s2mod, s2(0)))
    }
    else if (j < 1) (modifyString(s1mod, s1.slice(0, i)), s2mod)
    else if (i < 1) (s1mod, modifyString(s2mod, s2.slice(0, j)))
    else {
    val (suppr, subst, ins) = (matrix(i - 1)(j), matrix(i - 1)(j - 1),
    matrix(i)(j - 1))
    if (suppr < subst)
    findOperations(suppr, i - 1, j, modify(s1mod, s1(i - 1)), s2mod)
    else if (ins < subst)
    findOperations(ins, i, j - 1, s1mod, modify(s2mod, s2(j - 1)))
    else if (subst < dist)
    findOperations(subst, i - 1, j - 1, modify(s1mod, s1(i - 1)),
    modify(s2mod, s2(j - 1)))
    else
    findOperations(subst, i - 1, j - 1, s1(i - 1) + s1mod, s2(j - 1) + s2mod)
    }
    }
    findOperations(distance, s1.length, s2.length, "", "")
    }
    def min(suppr: Int, subst: Int, ins: =>Int) = {
    if(suppr < subst) suppr
    else if (ins < subst) ins
    else subst
    }
    }
    def editDistance(s1: String, s2: String): Int = EditMatrix(s1, s2).distance
    def showMatrix(s1: String, s2: String) = EditMatrix(s1, s2).print
    def showDistance(s1: String, s2: String) = EditMatrix(s1, s2).showDistance
    def showDistance(s1: String, s2: String, sep: String) = EditMatrix(s1, s2).showDistance(sep)

    private def separators(s: String) = (firstSeparator(s), secondSeparator(s))
    private def firstSeparator(s: String) = if (s.isEmpty) "" else s(0).toString
    private def secondSeparator(s: String) = {
    if (s.size < 2) firstSeparator(s) else s(1).toString
    }
    }


    Conclusion

    What's the conclusion? Computer science is useful of course, but you only recognize it once you know it!

    08 May 2008

    Algorithmic panic - take 2

    Shame, shame, shame.

    The Blog Writing Rule

    Writing at least one blog entry per month. That should be feasible, no? Unfortunately, last Friday, I was already more than 10 days late, so I had to do something!

    And, when pressing the "Post" button, I had this awkward feeling that something was not really right with my "solution". Not really on the "speed" side because I knew that my list accesses were sloppy, but even on the "correctness" side. But I was past the date, damn it!

    Fortunately, someone's watching

    Ok, enough justifications. I was in fact very pleased to get so many insightful comments, be it on my blog, or on reddit. It's a pleasure to see that so many people care for The Truth on the Internet ( ;-) )

    So I tried my best to review things up and to derive the maximum number of lessons out of theses errors. I'll start with that, then I'll copy the revised version of the algorithm.

    Lessons learned

    1. Check your definitions. The median definition is very straightforward,... if you have an odd number of elements. For an even number, you can elaborate several definitions, such as that one. For the code below, I choose to take define the median as a pair of values, which is both "middle" elements if the list is even. Pairs of values are then conveyed across all computations, so that it's always possible to eventually take the mean value if you feel like it

    2. Don't trust test generation. I promise my tests were green when I posted! However, the generation parameters were very bad: the number of tests was too small, the number and range of elements in the lists also. The solution here was tested on larger samples (up to 8000 tests), with larger lists (of same size or different sizes)

    3. Check your invariants. In this kind of "Divide and Conquer" approach, I should make sure that I have indeed the same problem, on a smaller scale, after dividing it. The code below shows that it is possible to take the same number of elements on each list, so that the median of the resulting lists is unchanged

    4. Know your data structures. I knew that the most basic list was not necessarily efficient but I must say that I didn't check anything. And, in fact, when Jorge pointed out that List had an O(n) access for size, I was quite surprised. The other interesting thing is that optimizing an operation can be totally feasible but quite tricky to implement (see the medianOfSortedListAndOneElement function below). And of course, takeWhile(_) was pretty bad!

    The algorithm

    First of all, lets start by the definition of the median as a couple of values, which may be the same if the list has an odd number of elements:

    case class ExtendedSeq(list: Seq[Int]) {
    def median: (Int, Int) = {
    if (list.isOdd)
    (list(list.size / 2), list(list.size / 2))
    else
    (list(list.size / 2 - 1), list(list.size / 2))
    }
    def isOdd = list.size % 2 != 0
    }

    If elements access and size are O(1) as in the RandomAccessSeq collection, that should be ok in terms of complexity (thanks Jorge).

    Here is the heart of the algorithm:

    def median(l1: Seq[Int], l2:Seq[Int]): (Int, Int) = {
    if (l1.isEmpty) l2.median
    else if (l2.isEmpty) l1.median
    else if (l1.size == 1) medianOfSortedListPlusOneElement(l2, l1(0))
    else if (l2.size == 1) medianOfSortedListPlusOneElement(l1, l2(0))
    else {
    val (m1, m2) = (l1.median, l2.median)
    m1.intersection(m2) match {
    case Some(m) => m
    case None => if (m1 < m2) median(trimLists(l1, l2))
    else median(trimLists(l2, l1))
    }
    }
    }

    The code above starts by checking some special cases: one empty list, a list + one element, then 2 "regular" median values.

    The first observation is that, if the median values (which are pairs of values) have a non-empty intersection, this intersection will be the median of both sorted lists.

    This is the not-so readable code for checking if there is an overlap between 2 pairs:

    case class ExtendedPair(pair1: (Int, Int)) {
    def intersection(pair2: (Int, Int)) = {
    if (pair2._1 <= pair1._1 && pair1._2 <= pair2._2) Some(pair1)
    else if (pair1._1 <= pair2._1 && pair2._2 <= pair1._2) Some(pair2)
    else if (pair1._1 <= pair2._1 && pair2._1 <= pair1._2 && pair1._2 <= pair2._2)
    Some((pair2._1, pair1._2))
    else if (pair2._1 <= pair1._1 && pair1._1 <= pair2._2 && pair2._2 <= pair1._2)
    Some((pair1._1, pair2._2))
    else None
    }
    }

    Finally, if there is no overlap, we need to remove elements from both lists so that the median of the remaining 2 lists will be the same as the median of the original lists:

    def trimLists(l1: Seq[int], l2: Seq[Int]) = {
    val removableElements = if (l1.size < l2.size) l1.size / 2 else l2.size / 2
    (l1.drop(removableElements), l2.take(l2.size - removableElements))
    }

    This time, I removed the same number of elements below the lower median and above the higher one (but still, a written mathematical proof would be more satisfying than "it's obvious that,...").

    On the complexity side, I still have to check that I can find a data structure (a Seq) providing drop and take operations in O(1). From what I read of the implementation of RandomAccessSeq, that should be the case. RandomAccessSeq is using indexes to provide O(1) "slicing" operations as suggested by Mikko in the comments of the previous post.

    Brutal force

    And finally, I can't resist showing you the horror of finding the median of a sorted list and a supplementary element in O(1). There may be a subtle trick to do that (please say, if you find it!), but I used the brutal force:

    def medianOfSortedListPlusOneElement(list: Seq[Int], element: Int) = {
    if (list.size == 1){
    if (element >= list(0))
    (list(0), element)
    else
    (element, list(0))
    }
    else if (list.isOdd) {
    if (element >= list(list.size / 2)) {
    if (element <= list(list.size / 2 + 1))
    (list(list.size / 2), element)
    else
    (list(list.size / 2), list(list.size / 2 + 1))
    } else {
    if (element >= list(list.size / 2 - 1))
    (element, list(list.size / 2))
    else
    (list(list.size / 2 - 1), list(list.size / 2))
    }
    } else {
    if (element >= list(list.size / 2 - 1)) {
    if (element <= list(list.size / 2))
    (element, element)
    else
    (list(list.size / 2), list(list.size / 2))
    } else {
    (list(list.size / 2 - 1), list(list.size / 2 - 1))
    }
    }
    }

    Not pretty, uh? Like the final approach for the 4-colors theorem.

    Measuring the complexity

    On my way to this post, I wanted to implement something which would store the test data and say if the curve looks like an O(log(n)), an O(nlog(n)),... In fact it doesn't seem so easy to do without any human validation and tweaking of the test data size until the complexity really shows. I'm thinking that using an utility to graph the performances and compare it with known complexities would be a good first step.

    But maybe driving the test generation so as to get a good confidence on the possible complexity of the algorithm would be even better. I'll try to have a look at that,... Maybe for my next post?

    Thanks for all the comments, I hope I didn't add more and more silliness to my previous errors.

    PS: I liked a lot Tom's comments about the 2-keys indexing problem. Indeed, the problem was underspecified, in terms of access frequency, memory, etc,... And a log(n) solution would certainly be ok in my specific case.

    02 May 2008

    Algorithmic panic

    Last week I read a blog post about an interview for Google and I thought: "Oh my god, I don't know how to do that, I'm lost, I have no idea, I will never find the solution".

    Flashback

    Two weeks ago, I've ordered and started reading the excellent book, "The Algorithm Design Manual". That book is very good. Teaching algorithms and data structures can be something very dry when you consider it from a very scholar perspective. But it becomes really fun and challenging when you realize that:
    • it solves real worthy problems
    • no amount of processing power can be overcome a clever algorithm when there is one
    • there's often no "right" solution but a combination of different approaches with different trade-offs
    So the book is filled with "war stories" showing the author investigating some problems, trying to ask relevant questions until there's a "ah-ah" moment where the problem is sufficiently characterized. Then the solution is refined to get a completely satisfying result.

    Decode this!

    For example, the author and his team had to provide a new way to decrypt DNA fragments, knowing that there was a new technique using small probes returning small fragments of the whole string. Say your DNA is ATGCCTCGATTG, the probes will find AT, TG, GA, TT, TG, all of which are substrings of the initial string. And from all those pieces, you have to find the original DNA string. For this kind of problem, the sheer number of elements kills instantly any brutal-force approach. Originally they had to sequence DNA fragments of 50.000 characters, knowing that more that 1.5 million pieces should be combined to get the answer. Don't try this at home!

    Binary tree > HashTable > Suffix Tree

    For their algorithm to work they had to set up a dictionary allowing the search of substrings of length k inside strings of length 2k. The question is: how to do that very efficiently? A student proposed a HashTable which would do the job in O(log(k)). But this was still too slow! Hey, what can be faster than a HashTable??!! A Suffix Tree.

    In this specific case they were searching elements which looked very close to one another, just being different by one character. And a suffix tree happens to organize the suffixes of a set of strings so that it's easy to search for a string which is just one character away.

    Understanding the structure of the problem yielded much better results than a HashTable: for a 8000 characters long DNA, the HashTable time was 2 days against 650 seconds for the SuffixTree (the "compressed" version, because the original one was blowing up the memory!). That was my "ah-ah" moment.

    The dreadful interview question

    So I thought I was ready for any algorithmic question. Until I read the blog: "find the median of 2 sorted lists in O(log(n))". I don't know why, reading that blog, I imagined myself over the phone, trying to solve this problem and my mind got totally blank. Panic.

    The same night, going to bed, I told myself: ok, relax, have a fresh look at it. And I slept happily a few minutes later because the principle of the solution wasn't that difficult.

    First of all, the median of a sorted list is the middle element. That's an O(1) search! Then, given the medians for each list, the median of both lists is something like the median of the 2 sublists of all elements between median1 and median2. That's where we get our O(log(n)) from, because with a recursive search, we're pretty sure to cut the problem size by 2 at each step.

    I programmed the rest the day after. Again, I think that this is a tribute to Scala. The result is really readable and I used ScalaCheck to verify it by generating lists of same and different sizes. On the other hand, I had hard time figuring out the proper bound conditions (ScalaCheck was very helpful here):

    trait Median {
    def median(l1: List[Int], l2:List[Int]): Int = {
    if (l1.isEmpty || l2.isEmpty || l1.last <= l2.head) (l1 ::: l2).median
    else if (l2.last < l1.head) (l2 ::: l1).median
    else {
    val (m1, m2) = (l1.median, l2.median)
    if (m2 < m1) median(l1.takeBetween(m2, m1), l2.takeBetween(m2, m1))
    else if (m2 > m1) median(l1.takeBetween(m1, m2), l2.takeBetween(m1, m2))
    else m1
    }
    }
    implicit def toExtendedList(list: List[Int]) = ExtendedList(list)
    case class ExtendedList(list: List[Int]) {
    def takeBetween(a: Int, b: Int) = list.dropWhile(_ <= a).takeWhile(_ <= b)
    def median = list(list.size / 2)
    }
    }


    Data structures everywhere

    Funnily, yesterday, one of my colleagues asked me if I knew an easy, fast and clever way to access some values classified with 2 keys:
    • there's only one value for (key1, key2)
    • she wants to get the value for (key1, key2) (fast,...)
    • she wants to get all values for key1 (fast again,...)
    • she wants to get all values for key2 (fast also,...)
    This looks like a very classical problem for Java programmers but surprisingly I found no existing, open-source, solution for this (if you know that, please tell me. I looked at things like TreeMaps or MultiMaps for example but they don't fit the requirement of a fast 2 key search with either of the keys).

    After some research and some thinking we concluded that 3 hashmaps sharing the values and dedicated to answer each different query fast would be the best thing to do. But now that I know that HashTables are not the ultimate solution to everything,...

    13 March 2008

    PDD: Properties Driven Development

    Quick quizz: 1 + 2 =? and 1 + 2 + 3 =? and 1 + 2 + 3 + 4 =?

    In other words, what is the result of the sumN function, which sums all integers from 1 to n?

    If we had to use a "direct" (some would say "naive") TDD approach, we could come with the following code:
    [Warning!! The rest of the post assumes that you have some basic knowledge of Scala, specs and Scalacheck,... ]

    "the sumN function should" {
    def sumN(n: Int) = (1 to n) reduceLeft((a:Int, b:Int) => a + b)
    "return 1 when summing from 1 to 1" in {
    sumN(1) must_== 1
    }
    "return 2 when summing from 1 to 2" in {
    sumN(2) must_== 3
    }
    "return 6 when summing from 1 to 3" in {
    sumN(3) must_== 6
    }
    }

    But if we browse our mental book of "mathematical recipes" we remember that

    sumN(n) = n * (n + 1) / 2

    This is actually a much more interesting property to test and Scalacheck helps us in checking that:

    "the sumN function should" {
    def sumN(n: Int) = (1 to n) reduceLeft((a:Int, b:Int) => a + b)
    "return n(n+1)/2 when summing from 1 to n" in {
    val sumNInvariant = (n: Int) => sumN(n) == n * (n + 1) / 2
    property(sumNInvariant) must pass
    }
    }

    Even better, Scalacheck has no reason to assume that n is strictly positive! So it quickly fails on n == -1 and a better implementation is:

    "the sumN function should" {
    def sumN(n: Int) = {
    assume(n >= 0) // will throw an IllegalArgumentException if the constraint is violated
    (1 to n) reduceLeft((a:Int, b:Int) => a + b)
    }
    "return n(n+1)/2 when summing from 1 to n" in {
    val sumNInvariant = (n: Int) => n <= 0 || sumN(n) == n * (n + 1) / 2
    property(sumNInvariant) must pass
    }
    }


    This will be ok and tested for a large number of values for n. Using properties is indeed quite powerful. Recreation time! You can now have a look at this movie, where Simon Peyton-Jones shows that Quickcheck (the Haskell ancestor of Scalacheck) detects interesting defaults in a bit packing algorithm.

    Fine, fine, but honestly, all those examples look very academic: graph algorithms, mathematical formulas, bits packing,... Can we apply this kind of approach to our mundane, day-to-day development? Tax accounting, DVD rentals, social websites?

    I am going to take 2 small examples from my daily work and see how PDD could be used [yes, YAA, Yet Another Acronym,... PDD stands for Properties Driven Development (and not that PDD)].
    1. From the lift framework (courtesy of Jamie Webb): a 'camelCase' function which transforms underscored names to CamelCase names
    2. From my company software: some pricer extension code for Swaps where fees values have to be subtracted from the NPV (Net Present Value) under certain conditions
    I'll develop the examples first and try to draw conclusions latter on.

    Example 1: camelCase

    So what are the properties we can establish for that first example? Can we describe it informally first?

    The camelCase function should CamelCase a name which is under_scored, removing each underscore and capitalizing the next letter.

    Try this at home, this may not be so easy! Here is my proposal:

    def previousCharIsUnderscore(name: String, i: Int) = i > 1 && name.charAt(i - 1) == '_'
    def underscoresNumber(name: String, i: Int) = {
    if (i == 0) 0
    else name.substring(0, i).toList.count(_ == '_')
    }
    def indexInCamelCased(name: String, i: Int) = i - underscoresNumber(name, i)
    def charInCamelCased(n: String, i: Int) = camelCase(n).charAt(indexInCamelCased(n, i))

    val doesntContainUnderscores = property((name: String) => !camelCase(name).contains('_'))

    val isCamelCased = property ((name: String) => {
    name.forall(_ == '_') && camelCase(name).isEmpty ||
    name.toList.zipWithIndex.forall { case (c, i) =>
    c == '_' ||
    indexInCamelCased(name, i) == 0 && charInCamelCased(name, i) == c.toUpperCase ||
    !previousCharIsUnderscore(name, i) && charInCamelCased(name, i) == c ||
    previousCharIsUnderscore(name, i) && charInCamelCased(name, i) == c.toUpperCase
    }
    })
    doesntContainUnderscores && isCamelCased must pass

    This property says that:
    • the CamelCased name must not contain underscores anymore
    • if the name contains only underscores, then the CamelCased name must be empty
    • for each letter in the original name, either:
      • it is an underscore
      • it is the first letter after some underscores, then it becomes the first letter of the CamelCased word and should be uppercased
      • the previous character isn't an underscore, so it should be unchanged
      • the previous character is an underscore, so the letter should be uppercased
    Before running Scalacheck, we also need to create a string generator with some underscores:

    implicit def underscoredString: Arbitrary[String] = new Arbitrary[String] {
    def arbitrary = for { length <- choose(0, 5) string <- vectorOf(length, frequency((4, alphaNumChar), (1, elements('_')))) } yield List.toString(string) }


    This works and in the process of working on the properties I observed that:
    • the full specification for CamelCasing name is not so easy!

    • it is not trivial to relate the resulting name to its original. I had to play with indices and the number of underscores to be able to relate characters before and after. However, if that code is in place, the testing code is almost only 1 line per property to check

    • the properties above specify unambiguously the function. I could also have specify weaker properties with less code, by not avoiding to specify that some letters should be unchanged or that the CamelCased name contains an uppercased letter without checking its position.

    Example 2: Pricer extension

    The logic for this extension is:
    1. to have the NPV (NetPresentValue) being calculated by the Parent pricer
    2. to collect all fees labeled "UNDERLYING PREMIUM" for that trade
    3. to subtract the fee value from the NPV if the valuation date for the trade is >= the fee settlement date
    4. to apply step 3 only if a pricing parameter named "INCLUDE_FEES "is set to true, while another pricing parameter "NPV_INCLUDE_CASH" is set to false
    This looks certainly like a lot of jargon for most of you but I guess that it is pretty close to a lot of "Business" requirements. What would a property for those requirements look like (in pseudo Scala code)?

    (originalNPV, fees, valuation date, pricing parameters) =>

    if (!INCLUDE_FEES || NPV_INCLUDE_CASH)
    newNPV == originalNPV
    else
    newNPV == originalNPV - fees.reduceLeft(0) { (fee, result) => result +
    if (fee.isUnderlyingPremium && fee.settlementDate <= valuationDate)
    fee.getValue
    else
    0
    }

    The most remarkable thing about this property is that it looks very close to the actual implementation. On the other hand, Scalacheck will be able to generate a lot of test cases:
    • an empty fee list
    • a list with no underlying premium fee
    • a list with a fee which settle date is superior to the valuation date
    • a list with a fees which settle date is inferior to the valuation date
    • the 4 possible combinations for the values of the pricing parameters
    You can also notice that I use as the first parameter the originalNPV, which doesn't directly come from a generator but which would be the result of the original pricer with the other generated parameters (fees, valuation date, pricing parameters).


    Conclusion


    As a conclusion, and at the light of the 2 previous examples, I would like to enumerate the result of my recent experiments with Properties-Driven-Development:
    • First of all is that PDD is TDD, on steroids. In PDD, we also have data and assertions but data are generated and assertions are more general.
    • I don't believe that this replaces traditional TDD in all situations. There are situations where generating even 4 or 5 cases manually is easier and faster. Especially when we consider that making an exact oracle (the savant word for verification of test expectation) is sometimes tedious as in the camelCase function. In that situation developping the cases manually using the == method would have been much faster
    • PDD on the other hand allow the specify very clearly what is the rule. This is something that you would have to infer reading several examples when using TDD
    • On the other hand having several examples also facilitate the understanding of what's going on. "foo_bar" becomes "FooBar" is more easy to catch than "if a letter is preceded by,..."
    • PDD is very good at generating data you wouldn't think of: empty list, negative numbers, a string with underscores only,...
    • A tip: sometimes, it is useful to include in the generated parameters the result returned by the function you want to test. For example, in the second example, my parameters could be: (originalNPV, newNPV, fees, valuation date, pricing parameters). That way, when Scalacheck reports an error, it also reports the actual value you got when showing a counter-example
    • Sometimes the properties you want to check will almost mimic the implementation (as in example 2). I think that this is may be very often the case with business code if written properly or that this may show that your code is missing a key abstraction
    • It really gets some time to get your head wrap around finding properties. And soon you'll start thinking things like: "I know that property A, B and C characterize my function, but are they sufficient?" and you realize that you coming close to Programming == Theorem Proving
    As a summary, PDD is not the long awaited Silver Bullet (sorry ;-) ,...) but it is indeed a wonderful tool to have in your toolbox. It will help you test much more thoroughly your programs while seeing them yet another way.

    25 February 2008

    Better mocks with jMock (and specs)

    Now, I don't know how I managed to do without it. Now, I wonder how everyone can do without it. Now, I think that nothing big can be done without it.

    I'm not advertising a brand new toy, but I'm talking about mock objects. Whether they are real mocks or just stubs, it is almost impossible to unit test Java components without them. Not that you can't test them but if you really want to isolate a piece of code, mocks show up one way or the other.

    One of the best libraries for mock objects in Java is jMock. Yet, Java's verbosity makes it sometimes difficult to understand the intention of the mock expectations. Enter now jMocks with Scala!

    Some statistics about my blog

    Let's say I want to write another front-end to publish my posts to Blogger. I have encapsulated all Blogger functionalities in a Scala trait:

    trait Blogger {
    def allPosts: List[Post]
    def todayPosts: List[Post]
    def post(p: Post, tags: List[Tag]): Unit
    ...
    }


    Now I want to test a "Statistics" component which will compute some stats about my posts:

    object statsSpecification extends Specification with JMocker {
    "a statistics component" should {
    "return the number of posts for today" in {
    val blogger = mock(classOf[Blogger])
    val stats = new Statistics(blogger)
    expect {
    one(blogger).todayPosts will returnValue(List(Post("...")))
    }
    stats.numberOfPostsForToday
    }
    }
    }
    class Statistics(blogger: Blogger) {
    def numberOfPostsForToday: Int = blogger.todayPosts.size
    }

    In that short specification we:
    1. create a mock: blogger = mock(classOf[Blogger]). I would have preferred to write blogger = mock[Blogger] but there is no way in Scala to create an object from its type only

    2. Add an expectation in the expect block. Again here the loan pattern makes things a lot clearer than the corresponding "Double-brace block" in Java (even if it is a clever java trick!).

    3. Specify what the return value should be in the same expression by defining "will" as Scala infix operator. In the Java equivalent we would have to make a separate method call (which our favorite IDE may insist on putting on the next line!)
      one(blogger).todayPosts; will(returnValue(List(Post("..."))))
    Pushing further with nested expectations

    There is also a situation where using Scala and jMock could be a real win.
    [What follows is extracted from the specs Wiki, talk about reusability!]

    You need to mock an object, like a Connection, which is supposed to give you access to a service, that you also want to mock and so on. For example, testing some code accessing the Eclipse platform can be very difficult for that reason.

    Using specs you can use blocks to specify nested expectations:

    // A workspace gives access to a project and a project to a module
    case class Module(name: String)
    case class Project(module: Module, name: String)
    case class Workspace(project: Project)
    val workspace = mock(classOf[Workspace])

    expect {
    one(workspace).project.willReturn(classOf[Project]) {p: Project =>
    // nested expectations on project
    one(p).name willReturn "hi"
    one(p).module.willReturn(classOf[Module]) {m: Module =>
    // nested expectation on module
    one(m).name willReturn "module"}
    }
    }

    or

    // a workspace is a list of projects
    case class Project(name: String)
    case class Workspace(projects: List[Project])
    val workspace = mock(classOf[Workspace])
    expect {
    // the workspace will return project mocks with different expectations
    one(workspace).projects willReturnIterable(classOf[Project],
    {p: Project => one(p).name willReturn "p1" },
    {p: Project => one(p).name willReturn "p2" })
    }

    I haven't yet tested this capability on a real project but I clearly remember having had that kind of requirement.

    I hope that this short post can make you feel that using mocks can be easy and elegant, especially if you use them with Scala! (and specs,....)

    PS: Thanks again to Lalit Pant for showing the way with Scala and jMock

    15 January 2008

    Better unit tests with ScalaCheck (and specs)

    Writing unit tests can seem tedious sometimes.

    Some people tell you: "Hey, don't write unit tests only! Do Test-Driven Development". You write the test first, then the code for it. This way:
    • you end-up writing only the code that's necessary to deliver some concrete value for your customer/user
    • you drive the design of your system
    • you add frequent refactorings to the mixture to ensure your code stays clean
    Or even better, "Do Behaviour-Driven Development!". With BDD, you get nice executable specifications for your system, which can almost read like English.

    While I fully adhere to the above principles, I also think that there is a continuum between specifications and tests. And at the end of this continuum, it's all about testing that your software works. Even given silly inputs. Your unit tests should provide that kind of coverage.

    And it's not that easy. A single line of code can go wrong in so many different ways. Try copying a file. Here comes ScalaCheck to the rescue!

    Introducing ScalaCheck

    Using ScalaCheck, you define:
    • properties which should always be true
    • random data to exercise the property
    and ScalaCheck generates the test cases for you. Isn't it great?

    Let's take a concrete example to illustrate this, because I feel I almost lost my only reader here (thanks bro, you're a real brother).

    If you want, you Can

    Last week I started specifying and testing the famous Can class from the lift framework. The Can class is the Option class from Scala library, on steroids. [To Scala newcomers: there are many good posts on Option, Maybe (in Haskell), Either and all this monad folkore but I will send you to a concrete example here].

    Basically, a Can is either Empty (it contains nothing) or Full (it contains a value). This is a fairly common situation in software or elsewhere: the user with name "Smith" exists in the database (Full) or not (Empty), I got the power (Full) or I haven't (Empty).

    When a Can is empty, it can be enhanced with an error message explaining why it is empty. In that case, it will be a Failure object.

    Now, if you want to test an "equals" method working for all different cases you have to specify a lot of test cases:
    1. 2 Full objects which are equal
    2. 2 Full objects which are not equal
    3. 2 Empty objects which are equal
    4. 2 Empty objects which not equal
    5. 2 Failure objects which are equal
    6. 2 Failure objects which not equal
    7. A Full object and an Empty object (not equal)
    8. A Full object and an Failure object (not equal)
    9. A Failure object and an Empty object (not equal)
    When I said it could be tedious,... And I'm even simplifying the situation since Failures can be chained, optionally contain an Exception, etc,...

    Properties

    Here is the solution, implemented using specs and ScalaCheck, with the support of Rickard Nillson, author of the ScalaCheck project:

    object CanUnit extends Specification with CanGen {
    "A Can equals method" should {
    "return true when comparing two identical Can messages" in {
    val equality = (c1: Can[Int], c2: Can[Int]) => (c1, c2) match {
    case (Empty, Empty) => c1 == c2
    case (Full(x), Full(y)) => (c1 == c2) == (x == y)
    case (Failure(m1, e1, l1),
    Failure(m2, e2, l2)) => (c1 == c2) == ((m1, e1, l1) == (m2, e2, l2))
    case _ => c1 != c2
    }
    property(equality) must pass
    }
    }
    }

    How does it read?

    "equality" is a function taking 2 Cans. Then, depending on the Can type, it says that the result from calling the equals method on the Can class should be equivalent to calling equals on the content of the Can if it is a Full Can for instance.

    Create a "property" with this function and declare that the property must pass. That's all.

    Well, you may want to have a look at what's generated. Add the display parameter:

    import org.specs.matcher.ScalacheckParameters._
    ...
    property(equality) must pass(display)

    Then you should see in the console:

    ....
    Tested: List(Arg(,Failure(cn,Full(net.liftweb.util.CanGen$$anon$0$UserException),List()),0),... Tested: ...
    Tested: ...
    ....
    + OK, passed 100 tests.

    And if one test fails:

    A Can equals method should
    x return true when comparing two identical Can messages
    A counter-example is 'Full(0)' (after 1 try) (CanUnit.scala line 21)

    But you may have, at this point, the following nagging question: "Where does all this test Data come from?". Let's have a look below.

    Generating data

    Data generators are defined "implicitly". You define a function which is able to generate random data and you mark it as "implicit". When ScalaCheck tries to generate a given of object, it's looking for any implicit definition providing this. Like:

    implicit def genCan[T](dummy: Arb[Can[T]])
    (implicit a: Arb[T] => Arbitrary[T]) = new Arbitrary[Can[T]] {
    def getArbitrary = frequency(
    (3, value(Empty)),
    (3, arbitrary[T].map(Full[T])),
    (1, genFailureCan)
    )
    }

    This code says that generating a Can, optionally full of an element of type T, which has its own implicit Arbitrary generator, is like choosing between:
    • an Empty object, 3 times out of 7
    • an arbitrary object of type T, put in a Full object, 3 times out of 7
    • a Failure object (which has its own way of being generated via another function), 1 time out of 7
    [The "dummy" parameter is here to help Scala type inferencer, AFAIK. The world is not perfect, I know]

    Here is the Failure generator, which make heavy use of ScalaCheck predefined generation functions:
    def genFailureCan: Gen[Failure] = for {
    msgLen <- choose(0, 4)
    msg <- vectorOf(msgLen, alphaChar)
    exception <- arbitrary[Can[Throwable]]
    chainLen <- choose(1, 5)
    chain <- frequency((1, vectorOf(chainLen, genFailureCan)), (3, value(Nil)))} yield Failure(msg.mkString, exception, chain.toList)


    In the above method,
    • choose returns a random int number inside a range
    • vectorOf returns a collection of arbitrary object, with a specified length
    • alphaChar returns an arbitrary alphanumeric character
    • arbitrary[Can[Throwable]] returns an arbitrary Can, making all this highly recursive!
    Random thoughts

    I hope this sparked some interest in trying to use ScalaCheck and specs to define real thorough unit tests on your system.

    The added value is similar to BDD, you will see "properties" emerge and this will have a better chance at producing rock-solid software.

    From now on, you too can be a ScalaCheck man! (see lesson 4)

    09 January 2008

    2008, a Scala year

    I apologize to Scala-interested readers, you'll have to scroll down to find something vaguely related to Scala! The first part is a pseudo-retrospective on my personal objectives for the past two years.

    [non-scala]
    "There's always a missing quote" - me

    I was looking for a way to open this post with a brilliant quote about setting up personal objectives but after spending several seconds (at least) searching the web, I found none which meant precisely what I wanted to convey about having personal objectives. So I may just tell my own story.

    First year

    Two years ago, I had this so original New Year idea of choosing 2 personal objectives for the year to come. Notice that I didn't say "resolution". This wasn't something I wanted to drop after half an agonizing month. My choice was: "Learn Ruby" and "Learn Japanese".

    "Learn Ruby" was very obvious considering my Java monotheism at that time and the relentless voice in my head moaning: "Leaaarnnn a new language each yeaaaar".

    "Learn Japanese" was less obvious. I wanted to work in Asia and having just a little bit of Vietnamese on my resume didn't seem very professional. But why Japanese? Because it looked very far from what I knew, and I thought: cool, I will read imported mangas! (If you told me that I would actually end up in Tokyo 1 year later, I would have swallowed my chopsticks!).

    Besides that, having 2 Japanese languages as "The objective of the year" look damn cool (Hey, you know that Ruby is also a Japanese language?)

    Verdict, one year later. I had done a nice immersion in Ruby, touching Rails, Camping, doing code katas, using it for mundane scripting, bugging my coworkers,...

    Japanese, on the other hand was embarrassing. A friend of mine told me: "Ah ah, you learn Japanese, good. Ohayo gozaimas'!". I said "What?". He had just told me "Good morning".

    My conclusion was: it's funny to have objectives, especially if you only have to fulfill the ones you fancy for real.

    Second year

    I tried the same experiment for the following year. But that time I was really leaving for Japan! With a job in finance, which I hadn't done for some time, using a thousands-of-java-classes software. Since I am a sensible person, I thought: don't put too much pressure on your shoulders: new life, new challenges, do something reasonable.

    My official and much touted objectives for 2007 were: "Learn Japanese" (and start with "Good morning" maybe this time) and "Learn my new company's product and succeed in my company".

    Where are we, one year later?
    • "Learning Japanese" was a self-sustaining objective since I had company-provided lessons starting from August. It's much easier with a teacher than alone. Go to the class, do your "Shukudai" (homework) and it should be fine
    • "Learning my company product and succeed in my company" is well,... a terrible objective per se. It was more a way of saying: focus on your job, not on something else. A non-objective, not very motivating in itself, I'm addicted to my job anyway. Besides, this is not something I totally own. There are so many things which are truly out of my control (like not being authorized to blast atrocious code or organize projects in a truly agile mode)
    Half-way through the year, I realized that having a motivating objective was like having something making you go the extra mile, diffusing energy and enthusiasm on the rest of your existence. I decided to finish the open-source project I had started as an experiment: specs.

    This year

    So what's in for this year? If I choose objectives for 2008, I:
    1. authorize myself to change my mind anytime. Life's too short and anyway my experience shows me that this cannot work if it's not pure pleasure

    2. select something which is deeply motivating, like learning something intriguing and new for the learning freak that I am (though I wish I was motivated by more cooler things to show-off in parties. Monads are hot on reddit but try that during a diner)

    3. try not to put too much on my shoulders, because sleeping should not be Option[Sleep]
    Which brings me to the quote of the day:

    "I can't do everything,..., today" - my wife, pretty submerged
    [non-scala]

    Now, dear Scala readers, here are my objectives for this year:
    1. continue to support specs, fixing issues and listening to users. I don't plan any major feature excepted maybe having another go at integrating JMock. However I will certainly add a myriad of small stuff (like a "skip" method, in 1.1.5)

    2. contribute to the lift project by adding documentation, specs and tests. I expect to get a deep knowledge of that awesome web framework, quality interactions with the community, personal satisfaction from contributing to others work, improvements for specs

    3. [as time permits] keep an eye on LiteralSpecifications with specs by creating a front-end wiki allowing you to write your specifications using a Markup language annotated with Scala code. The long-term objective is described in this paper
    My dream would be to meet you all during the next Scala lift off conference. I have to see if I can combine this with a SF assignment in my company's headquarters!

    Happy New Year 2008, I have no doubt that it is going to be a great "Scala year" despite the unavoidable hype and FUD!

    18 November 2007

    Software design is like a magic trick

    There's something I love at least as much as software development: my wife (Hey!! Give me back that keyboard, will ya?. I love you *more* than software development of course,...). So, what was I saying, ah, yes. There's something I love at least as much as software development: magic.

    And there are some interesting similarities between the design of a magic trick and the design of software. Let's take, as an example, the last functionality I have designed for specs (but not released yet).

    The effect

    When you start thinking about a magic trick, you just try to be creative, to focus on what will really make other peoples brain explode. Or, and I find this even more impressive, transport them emotionally in a real magic world. To that respect David Copperfield is an incredible magician, and there are lesser known magicians whose creativity and talent are as amazing: Jay Sankey, Juan Tamariz, Michael Ammar, Jean-Pierre Vallarino, Vito Lupo,... The list is long. All of them have spent hours just thinking: "Why is this magic?", "How can I make it more magic?". They think about the spectator and the effect first and before any consideration of how it could be done.

    In my case, it's a lot less romantic,... I just want the developer to be able to:
    • create a table containing data rows
    • have a header of Strings labeling each column
    • have the rows being typechecked so that the type of the elements in a given column is always the same
    • apply a function to each row and have the function parameters being typechecked against the row types
    • have a light syntax allowing the table to look like a table as much as possible (not a list of lists,...)
    Something like that:
    |"a"|"b"|"c = a + b"|
    | 1 | 1 | 2 |
    | 1 | 2 | 3 |
    | 2 | 2 | 4 | {(a:Int, b: Int, c: Int) => (a + b) must_== c }

    How can I use my target language, Scala, to do that? Without loosing the ideal representation above; I want to keep my effect as magical as possible!

    The method

    Let's say I want to make the Statue of Liberty disappear, this would be baffling, wouldn't it? But even with an incredible budget, will the New-York authorities allow me to place a huge trap below Ellis Island? No? So how did he do it ?!

    Here are 3 things I noticed with great magicians:
    • They have an incredible magic culture. They know every obscure method to make a coin disappear or a card change its color, including the name of the inventor, the year of publication and the thousands of tricks using it
    • They are always open to new stuff. Anything. Okito was just playing with a pill box when he invented the "Okito box". Michael Ammar actually listened to every single "great new idea" we had at our local magic club!
    • They can invest an incredible amount of time and energy to preserve the magic of the effect: exercise for hours for a single "invisible" move, research chemical catalogs, learn the order of 6 decks of cards by heart (you can find a Hollywood version of that in "The Prestige")
    That's what I tried to do with the DataTable feature: use all the Scala wizardry I knew of, be opened to new ideas and invest the maximum of energy so the feature is as simple as can be for the developer.

    Here was my first attempt:
    ("a", "b", "c = a + b") |
    ( 1 , 1 , 2 ) |
    ( 1 , 2 , 3 ) |
    ( 2 , 2 , 4 ) | { t => val (a, b, c) = t
    (a + b) must_== c }
    In that version, I used the following features:
    • Tuples have a litteral notation ( , , , )
    • You can create new operators, like | on tuples using implicit definitions
    • The definition of the | operator can make sure that I will always add Tuples having the same types for their elements
    • A tuple can be deconstructed as 3 values using "val"
    This was mostly what I wanted but not quite, so I searched again and eventually got to this:
    "a"| "b"| "c = a + b" |
    1 ! 1 ! 2 |
    1 ! 2 ! 3 |
    2 ! 2 ! 4 | {(a: Int, b: Int, c: Int) => c must_== calc.add(a, b) }

    Yes, almost my original intention! The most notable difference is the use of ! instead of | as a separator for the cells in the data rows. This is because operators beginning with | have a lower precedence over those beginning with ! in the Scala specification (6.12.3). So if I use |, I will have difficulties delimiting rows. I learned a new trick!

    Frankly, it's not as good as the ideal version but it's ok if you read | as a delimiter for the table boundaries (including the header) and ! for the actual data. Sometimes in a magic trick you change a line, bend the story a little and it is still a pretty good trick.

    And what about the rest of the magic? The first version only allowed to define a function taking a tuple as a parameter. Well, I worked a lot behind the scene to obtain that new version:
    • The DataTable class takes 20 type parameters. 20 is a limitation but should act like a warning anyway. Why would you seriously need more that 20 columns in your table? Can't it be refactored?
    • There are 20 DataRow classes, having from 1 to 20 type parameters. Each DataRow object can only be joined with a similar DataRow object using the | operator
    • The DataTable class has 20 methods to apply functions having 1 to 20 parameters. Applying each row to the function parameters is done in each of these methods. A nice side-effect of that is that I can use a function with less parameters than the row size
    • All that code is produced with a Ruby script to ease the work of the magician developer
    You can have a look at the current code, which may actually be clearer than the points above.

    Design and magic

    This comparison with Magic can add more credits to the "Design is a craft" theory. I'm pretty sure that you could do the same kind of comparison with some craft you're fond of. So what's next: "Software design is like Origami", "Software design is like Wood carving"?

    PS: for the Statue of Liberty trick, just Google for the explanation, you should get a glimpse of the kind of creativity those darn magicians can have!

    08 October 2007

    Scala to heaven, second step: anatomy of a scala script

    This objective of this post is to contrast some java and scala code aimed at accomplishing the same scripting task: cleaning-up my garbage system.

    I want to be able to count old items in a database and archive them (through my system API). Of course, if anything goes wrong, I want to be able to restore them.

    I'll show what is the approach I took using java then the corresponding scala-way of doing things.

    The Java way: connect to the server

    First things first: get a server connection. Typically, this is how I do it in java:

    DataServerConnection connection = ConnectionUtil.connect("me", "my password", "my environment file");
    // I do my stuff here

    Of course, when my job is over, I have to close the connection:

    connection.disconnect();

    But in this situation, and in plenty others like writing to an OutputStream, I may just forget to close your resource. So, here's:

    The Scala way: connect to the server

    There is, among a gazillion things, a very useful feature in Scala: the possibility to have parameters of a method evaluated lazily. This means that the parameter you pass to a method will be evaluated only when the method body requires it, and not as the method is called, as it is the case in Java.

    This way, I can write a better connect method:
    def connect(user: String, password: String, env: String, actions: => Any) = {
    val connection = ConnectionUtil.connect(user, password, env)
    actions
    connection.disconnect
    }
    And use it like that:

    connect("me", "my password", "my env. file", actions())

    The actions are only performed once the connection is open, and the connection is closed without having to think about it. And for even more readability, I can even use the following syntax:

    def connect(user: String, password: String, env: String)(actions: => Any) = {
    val connection = ConnectionUtil.connect(user, password, env)
    actions
    connection.disconnect
    }
    connect("me", "my password", "my env. file"){
    actions
    }

    Nice Ruby/blocks feel, isn't it? [for a better implementation of this pattern with try/catch and all, please check the Loan Pattern].

    The Java way: processing stuff

    For this script, the overall process is the same:
    • get some "Market data items" for some "type" and "currency"
    • count/archive/restore the oldest ones
    The usual way to do that in Java is to nest some for loops and do the job inside the most inner loop:
    for (String type : types) {
    for (String currency : currencies(type)) {
    for (String name : getMarketDataItemNames(type, currency)) {
    final int id = market().getMarketDataItemId(type, currency, name);
    doAction(action, type, id);
    }
    }
    }
    This buries deep inside the "selection" logic, the "action" logic. One alternative would be to construct first the list of elements to process, then process them. But in my case, this would mean dragging a very big chunk of the database in memory.

    The Scala way: processing stuff

    Scala offers the possibility to cleanly separate the selection logic from the action logic:

    // select items
    def items = for (itemType <- market.getMarketDataItemTypes.toStream;
    currency <- currencies(itemType);
    name <- market.getMarketDataItemNames(itemType, currency);
    itemId = getItemId(itemType, currency, name))
    yield (itemType, itemId, name)

    // archive items
    def archive(items: Iterable[Item]) =
    for ((itemType, itemId, itemName) <- items)
    archive(itemType, itemId, itemName)

    archive(items)

    The for/yield construct returns ("yields") a list composed of "items" (type, id, name), ready to be processed by the archive function. The interesting thing is that this list doesn't have to be build in memory at once. It is a Stream, i.e. a list whose elements are being fetched as they are needed.

    The Java way: aggregating results

    The last step in my script is to display the current number of processed elements as well as their total number. I did it very simply with Java:
    final int totalProcessed = 0;
    for (String type : types) {
    for (String currency : currencies(type)) {
    for (String name : getMarketDataItemNames(type, currency)) {
    final int id = market().getMarketDataItemId(type, currency, name);
    System.out.println(action + " item: " + name);
    int processed = doAction(action, type, id);
    totalProcessed += processed;
    System.out.println("Done: " + processed + " Total: " + totalProcessed);
    }
    }
    }

    Again, the reporting logic is buried inside the loops, and this may fine indeed for a simple script. In other circumstances, you may want to be able to achieve a bit more independence between the functionalities:

    The Scala way: aggregating results

    The idea here is to be able to write:

    report(count(items))
    report(archive(items))
    report(restore(items))

    With the same report function which will:
    • take a list of Report resulting from each action,
    • print the current Report
    • cumulate the current Report with a running total Report
    • without having to process everything, then do the reporting,...
    I will not go in every detail of the exact solution (which is a bit complex to my taste in fact, see below) but here are the principles. First of all, each action yields its result as a Report object, containing the name of the processed item and the result of the processed action:
    def archive(items: Iterable[Item]) =
    for ((itemType, itemId, itemName) <- items)
    yield Report(itemName, archive(itemType, itemId, itemName))


    Then, the report function judiciously uses the reduce function to do the sum and report each element:

    def report(reports : Iterable[Report]) = {
    reports.reduceLeft {(x:Report, y: Report) =>
    (x + y).report
    }
    }

    Not so readable for the non-expert eye, right?! Press F1:
    • report iterates over a list of Reports
    • it sums all elements 2 by 2 until we have a final result. List("h", "e", "l", "l", "o").reduceLeft((a: String, b: String) => a + b) would produce: "hello"
    • before returning the summed element, it calls the report function to allow the aggregated report to print itself to the console:

    class Report(itemName: String, processed: Int) {
    var total: Int = 0
    def +(c: Report) = { c.total = total + c.processed; c }
    def report = { reportItem; reportTotal; this }
    def reportItem = println("Item " + itemName + ": " + processed)
    def reportTotal = println("total number: " + total)
    }
    Conclusion

    The sad truth is that my real-world solution is a tad more complex that the one presented above. In the "real-life", I have different types of Reports because each action doesn't bring the same kind of results.

    count only returns counted elements, archive and restore return deleted elements + processed elements (to double-check that the action is ok). Abstracting over this and defining a Summable interface to provide addition over both Int and Tuples proved a bit more challenging than using the plain Java solution.

    But the good news is that as long as you're not looking for too much abstraction, you will find really neat ways to write common programming logic in Scala.