Archive for the ‘Uncategorized’ Category.

Scala Compiler Quirks

Recently I have been dabbling with scala a bit. As it happens I found a few quirks in the compiler.

So does the following bit of code compiler and, if so, what does it print?

object Example {
    val x = y
    val y = true
 
    def main(args: Array[String]) {
        print(x);
    }
}

Yes you’ll get false and that is plain wrong. In my opinion a compiler error would have been fine and ideally, as there are no cycles it would have just printed true.

Another major selling point of scala is it’s pattern matching mechanism. A very convenient feature is the compiler’s ability to print a warning, if the cases provided are not exhaustive. A very simple case of such a non-exhaustive match is this:

object CaseExample {
      def main(args: Array[String]) {
          val b = args.length == 1
          b match {
              case true => print("True")
          }
 
      }
  }

Unfortunately the compiler doesn’t complain at all. After some googling I came across SI-3111. My own problem was slighty, but only slightly more complicated. I matched tupels of Options against Some and None.

We have been bitten by both problems, that lead to really subtle bugs. This is really unfortunate, because the compiler can do a lot more in a language like scala. The first problem gets even caught by javac.

A third shortcoming of scala can be easily fixed. Set the tab size to four spaces and your code will
look a lot more structured.

To me it seems like the scala compiler unnessarily discredits the idea of strong static checks by a somehwat quirky implementation.

Jour Fixe Zubehör

Bin schon vor längerem über dieses Design gestolpert. Leider scheint es nicht produziert zu werden.

Working Effectively with Legacy Code

I have just finished reading Michael Feathers’ Working Effectively with Legacy Code. The book gives a lot of very concrete examples of how to improve code and make it testable. To my tastes he is exaggerating the whole code without test is legacy code thing, which in the naïve reader might lead to the impression that a test is all it needs for code to be good.

As I am going to sell my copy at favourable rate to one of my colleagues, I’ll just list a few things I found intersting:

  • Chapter 15 – My application is all API calls. He uses a very good example of a mailing list server to illustrate how to get around problems with external API dependencies. He distinguishes to approaches “Skin and wrap the API” and “Responsibility-based extraction”. I am strongly favouring the second approach as I find it leads to more relevant abstractions and not wrapping for the sake of wrapping…
  • Another theme in the book is understanding code. He mentions a few nice techniques:
    • Effect analysis (dataflow analysis) using pen and paper
    • Mapping out your way through the code base while reading on a piece of paper
    • Printing the code and doing listing markup using marker pens.
    • Scratch refactorings while reading code, that are thrown away and whose sole purpose is helping to understand the codebase and on a similar note delete unused code you find while reading
    • Telling the story of the system. This is done at several levels starting with a high level description that has a lot of generalisations. This practice helps people to develop a shared vision and also highlights discrepancies between the system and the story.
    • Naked CRC-Cards – somewhat poorly named as actually it’s naked object cards. Use white index cards on a table to represent objects. Tell story as you place and rearrange them.

There is a nice example for separation of concerns (he uses the term SRP, which I don’t like) on page 247 describing an expression evaluator.

Adapt parameter refactoring. If the parameter type is too complicated for stubbing etc, look at the use of the parameter and introduce a wrapper around the original object that just exposes what the current method needs. Example HttpServletRequest gets wrapped in ServlatParameterSource which implements a new ParameterSource interface.

On a similar note primitivise parameter. Instead of passing in our wrapping an expensive abstraction just pass in the required “values”. This of course very dangerous as it breaks encapsulation. On the other hand it could lead to the extraction of roll based primitive interfaces (a bit like the adapt parameter pattern)

Books to Go

Ab sofort ist der podcast zur neuen hervorragenden “BOOKS TO GO”-Taschenbuchreihe des dtv verfügbar.

Seaside

Last Thursday I had the honour of giving a talk on the seaside web framework. It is implemented in smalltalk and it provides a lot of interesting ideas:

  • Using builders rather than templates to spit out html.
  • A component model for composing interfaces as well as for expressing page flow.
  • Encaspulating Ajax goodness
  • Excellent debugging and monitoring tool support

  • An interesting optional metadata driven approach to the UI (magritte)

It has a small but constantly growing and dedicated community. Below I added a list of starting points

Links

  • The seaside homepage
  • The tutorial of the HPI is probably the best way to learn about seaside and its world
  • Ramon Leon is blogging regularly about more advanced topics.
  • Lukas Renggli is the creator of magritte
  • DabbleDB is implemented in Seaside and a very interesting application.
  • No Snowday for me

    As indicated earlier I didn’t take a “snowday” off work. Here is a picture of my bike down in aldgate where I worked that day:

    fahrrad_im_schnee

    Return on Investment

    The other day I bought mudguards and put them on my bicycle. I did pay off very well today.

    Schöne Wörter

    Muss gerade mal festhalten, dass “halbseiden”, “überspannt” und “altbacken” schöne deutsche Wörter sind, die sich so nicht ohne weiteres ins Englische übersetzen lassen.

    Test Sclerosis – The Trouble with Unit Tests

    Your typical system, written in a nice object-oriented way performs its task using a number of collaborating objects that send methods to each other. Ignoring some of the complexities like objects actually creating new objects in response to message, we can draw a diagram like the one below:

    Each arrow represents a method call. Now for mocking and unit testing, usually you want to test one particular part of the system. In a lot of cases I have seen so far this would be a single object. Somewhat like this:

    As we are all aware of dependencies by now and know how we inject them, the constructor for this object probably takes its two collaborators as parameters. So we can easily pass in mock objects, that are used to mimic the actual collaborators behaviour and/ or verify that the object under test actually does trigger certain actions in its collaborators:

    So far so good. What is the problem with this approach?
    Another thing, that the well-adjusted programmer does quite often, is refactoring. While a lot of people think of rename class/ method/ variable, when refactoring is mentioned, these are obviously the trivial cases. Let’s consider a serious change to a subsystem of our hypothetical application:

    We might actually introduce some new objects to get a better factored system (contrived example). So we end up with the following:

    If we actually went down the hard-core mocking road with that system the place we start from actually looks like this:

    The red lines indicate interactions that are now asserted and mocked out throughout the tests. To do a refactoring like the one proposed above you have to change a whole lot of test cases. Even worse I don’t have the confidence, that the behaviour is still the same, because I had to fiddle with the tests during the refactoring, even though the “outer” interface remained the same. I call this situation test sclerosis as the tissue of your application is hardened by all the tests and mocks and thereby loses a lot of flexibility.

    How to avoid this situation?

    One important question that helps avoiding getting into the above mentioned situation is asking about the value of writing a particular test. Generally we write tests for the following reasons (not a complete list):

    • Ensure the code actually provides the required functionality.
    • Avoid regression (safety net).
    • Help with design.
    • Make debugging easier.
    • (Make you feel confident.)

    It seems to me that naive massively stubbed, or mocked unit tests usually don’t help much with these goals.

    The general advice seems to be to choose your units carefully. Single objects are probably too fine grain. Look for natural subsystems. You might for example stub out the file system or an external system that has a very clearly defined interface, e.g a mail server. Keeping the number of mocks and stubs needed per test-case low (i.e. zero or one) is a good tactic. Try to test things that are interesting and non-trivial.

    Es schneit in London

    Man sollte es kaum für möglich halten, aber es schneit: