Lean startup language design

Dart

At a recent hackathon I was noodling around with Dart. I thought, it was great that Google made it particularly easy to start playing with their new language by putting an interactive shell – the Dartboard – on its home page. No download, no installation, instant coding. Very nice. On the other hand they made it unnecessarily hard to find any information about the language on the internet by calling it Dart. Particularly when you search about throwing exceptions…

Trying to implement a small project in this new language I haven’t seen before made me wonder: How effective do language designers use feedback? On Dart’s website they ask for feedback, which is mostly organized in groups. What they should really do is to bring in some developers and monitor them as they try to solve simple tasks with the language under development. After all, creating a language is just another software project with end users. Or better still, at this stage they should  log and analyse compiler errors from the shell on the website. If people keep producing the same compiler error over and over it is probably an indicator that this particular construct of your hip new language just might not be very intuitive.

Let’s assume Google logged and analysed what happened in our session from this week’s hackathon – and they most likely did, they would come to the conclusion that having two different notations for creating a function was confusing for us. Especially, because only one of them caters for certain scenarios. Either that, or that there were two idiots in front of the computer who needed 20 minutes to figure it out. You can judge for yourself:

main() {
  (function() => print('Hello again'))();
}

This works just fine. It creates a function that prints ‘Hello again’ and executes it.

main() {
  (function() => throw new Exception())();
}

This on the other hand gives you a (not very useful) compile time error that the token ‘throw’ and ‘new’ are not expected. While this is entirely true, it sent us in the wrong direction to check how to throw exceptions. While the actual mistake was that you can only use expressions with the => notation. If you want to use statements, like throwing an exception, you need to omit the arrow and use a block with curly braces instead.

main() {
  (function() {throw new Exception();})();
}

I hope other language designers will follow Google’s example and show off their language as early as possible to get feedback on their decisions. Maybe even without the developers being aware of it. I don’t see any reason why lean startup ideas shouldn’t be applied to the creation of a new language. Can you?

Kotlin and Ceylon to open their doors by the end of the year

sim city start

The residents of Java are waiting. Waiting for the day when another city will rise to supremacy in JVMland. These days they are looking north towards the functional territories and watch with interest as the new cities Kotlin and Ceylon are being built. Many Java inhabitants are tired of the city they live in. Not just since their home town is ruled by Amun, who is said to have just swallowed his predecessor Ra. For years they have been waiting for new facilities to be constructed. Facilities they have seen on weekend trips to other cities like the very hip Ruby or which they got to know and love while going to school in towns like Haskell. The people of Java are restless. While they are very familiar with their home town which provides all the basic features to get by, they are craving for some place new and exciting.

While it is not impossible the move to another city the adventurous have to bear some risks. New cities are having a hard time attracting companies to create jobs for willing new citizens. Often only companies in niche industries are willing to venture outside the secure boundaries of the Java megalopolis. Not few explorers who sought their luck in other cities eventually came back to Java because in the end it turned out to be more convenient. Big companies and with them their employees won’t even consider moving, before a new city has a proven success record. Many cities tried. Non succeeded so far.

The creators of Kotlin, still citizens of Java themselves, claim to have studied and learned from these failed attempts. They are promising all the best features from what is probably their biggest contender – Scala town – while having way easier infrastructure. They are also advertising stellar public transportation (aka Inter Domicile Express), which should help new citizens tremendously with getting to feel at home in the new environment. Like Scala they also aim for seamless communication with all districts in Java.

On first glance Ceylon’s layout looks very similar to Kotlin’s and some even suggest they should join forces to enhance their chances to succeed. But since the foundations of both cities are already done and dusted this seems very unlikely.

Kotlin and Ceylon are planning to open their doors by the end of the year and the weary inhabitants of Java are sitting on their packed bags – waiting.

The functional breakthrough … the back door

Back DoorEver since my first encounter with Haskell in my very first week at university I have been waiting for functional programming to become more widely spread and to find acceptance in the industry. Still… waiting…

Playing around with Scala these days, I have come as close as ever to use functional programming for something non-academic. Is Scala a functional programming language? You bet. But isn’t it also an object-oriented language? Certainly. Arguably more so than other object-oriented languages like Java (link). This might be the foot in the door for functional programming. Because object orientation is so dominant and functional programming requires such a different way of thinking, it is basically impossible for functional programming to compete with the market leader. And what do you do if you can’t beat them? That’s right. You join them.

Object-functional languages like Scala provide the perfect ground for programmers, who know their object-oriented languages inside out, to get to know the benefits of functional languages. You can get your code working by programming in the object-oriented way you live and breath, then you refactor it and add some functional touch to it. Or rather, you remove some of the wordy cumbersome cruft replacing it by more elegant code. And once you get to know and love the expressiveness that is functional code you will start writing it in the first place. And with that become a better developer.

By now, I have stopped waiting for a breakthrough of a pure functional language. But with that I am also sure that things like higher-order functions and pattern matching will find their way into the mainstream. One way or another.

Image by: So gesehen

Conway’s Game of Life in Scala

I attended a Code Retreat yesterday in Hamburg. As usual we used Conway’s Game of Life to practice our coding skills. I planned to do at least one session using Scala, but my Scala IDE wasn’t working any more, probably due to an incompatible upgrade of some description.

So, today I took the time to get my IDE up to scratch and implemented the game of life in Scala. It just had to be done. And since no-one forced me to delete my code after 45 minutes (as it’s common at code retreats) I actually got to finish it. Including console output. Bonus.

object GameOfLife extends App {
  var civilization = new Civilization(List((3, 1), (3, 2), (3, 3), (2, 3), (1, 2)), 10)

  civilization.printGrid
  for (period <- 1 to 100) {
    aGenerationPasses
    civilization = civilization.tick
    civilization.printGrid
  }

  def aGenerationPasses = synchronized {
    wait(100)
  }
}

class Civilization(seed: List[(Int, Int)], size: Int) {
  private val STAY_ALIVE = 2
  private val BE_BORN = 3
  private val grid = new Array[Array[Boolean]](size, size)
  seed foreach (cell => containsCellAt(cell._1, cell._2))

  def tick = {
    val nextGeneration = new Civilization(Nil, size)
    for (row <- 0 until size; col <- 0 until size)
      if (isCellAt((row, col)) && numberOfNeighboursFor(row, col) == STAY_ALIVE
          || numberOfNeighboursFor(row, col) == BE_BORN)
        nextGeneration.containsCellAt(row, col)
    nextGeneration
  }

  private def numberOfNeighboursFor(row: Int, col: Int): Int =
    areaAround(row, col) map wrap filter isCellAt length

  private def areaAround(row: Int, col: Int): List[(Int, Int)] =
    List((row-1, col-1), (row,col-1), (row+1,col-1), (row-1,col), (row+1,col), (row-1,col+1), (row,col+1), (row+1,col+1))

  private def wrap(cell: (Int, Int)): (Int, Int) =
    (((cell._1 + size) % size), ((cell._2 + size) % size))

  private def isCellAt(cell: (Int, Int)): Boolean =
    grid(cell._1)(cell._2)

  private def containsCellAt(row: Int, col: Int) =
    grid(row)(col) = true

  def printGrid = {
    println
    grid foreach {
      row => row foreach {
        cell => if (cell) print("*") else print(".")
      }
      println
    }
  }
}

The GameOfLife object runs the game by creating an initial civilization and then looping through a fixed number of generations, printing each of them along the way.

The civilization creates its next generation upon call of the tick method. This happens by applying (a simplified version of) the four rules of the game to each spot on the grid. Since I initialize the next generation with no cells, I only care about rules 2 and 4 that deal with alive cells.

Conway's Game of Life Rules

I decided to wrap the grid at the edges. So objects leaving the grid on the right don’t disappear, but re-enter on the left instead. This happens in the wrap method.

The numberOfNeighboursFor method is a bit magical. There is 6 method calls in a one-liner. Surely, people who are used to functional language list comprehensions can appreciate this. Read: In the area around the given cell coordinates (1) for each spot apply (2) the wrapping (3) then filter (4) by spots that contain a cell (5) and finally give me the length of the resulting list (6). Voilà.

I am not entirely happy about the use of a nested Array for the grid and the for loop in the tick method, but I couldn’t come up with a better solution. Suggestions welcome.

CI Gossip: Is Hudson asking Jenkins out again?

divorceAfter the recent divorce of Hudson and Jenkins following the tragical death of Hudson’s mother Sun and a long battle over trademark rights, Hudson seems to have come to senses and is planning to hand over the code to Eclipse.

I’ve seen Jenkins’ father Kohsuke in Hamburg earlier this week where he presented some stats on the project activities. I don’t remember the exact numbers, but he drove home the point that Jenkins is where the action is. It seems like Jenkins moved out and took the kids (the open source community) with her. Apparently lawyers don’t code. Who knew?

It appears that Hudson’s new foster parents Sonatype are driving the recent activities trying to reunite the once happy couple in the hope to revive the lethargic Hudson. It remains to be seen if Jenkins can forgive Hudson for what he put her through. After all the hard work to build up a life of her own, Hudson’s request for forgiveness seems almost too much to ask for.

The Bowling Game Kata in Scala

Here is the end result of my implementation of the Bowling Game Kata in Scala. You can see all steps including the tests on CodersDojo.org.

class BowlingGame {

  var rolls: List[Int] = List()

  def roll(pins: Int): Unit = {
    rolls = rolls :+ pins
  }

  def score: Int = {
    scoreRecursive(0, 1, rolls)
  }

  def scoreRecursive(currentScore: Int, frame: Int, rolls: List[Int]): Int = {
    frame match {
      case 11 => currentScore
      case f => rolls match {
        case 10 :: rollsTail // strike
          => scoreRecursive(currentScore + (rolls take (3) sum), f + 1, rollsTail)
        case first :: second :: rollsTail if (first + second == 10) // spare
          => scoreRecursive(currentScore + (rolls take (3) sum), f + 1, rollsTail)
        case first :: second :: rollsTail // normal
          => scoreRecursive(currentScore + (rolls take (2) sum), f + 1, rollsTail)
        case _ // incomplete game
          => throw new Exception("Only complete games can be scored.")
      }
    }
  }
}

Comparing this piece of code with the Java implementation from Uncle Bob (who, no doubt, knows how to write clean Java code) I would conclude that it is more expressive and concise. The pattern matching is a) shorter and b) makes the algorighm stand out more clearly. I do, however, appreciate that this might have to do with personal taste. But, what this implemenation with pattern matching does make trivial is to also score partial games. It just requires two more lines of code that seem almost obvious.

class BowlingGame {

  var rolls: List[Int] = List()

  def roll(pins: Int): Unit = {
    rolls = rolls :+ pins
  }

  def score: Int = {
    scoreRecursive(0, 1, rolls)
  }

  def scoreRecursive(currentScore: Int, frame: Int, rolls: List[Int]): Int = {
    frame match {
      case 11 => currentScore
      case f => rolls match {
        case 10 :: rollsTail // strike
          => scoreRecursive(currentScore + (rolls take (3) sum), f + 1, rollsTail)
        case first :: second :: rollsTail if (first + second == 10) // spare
          => scoreRecursive(currentScore + (rolls take (3) sum), f + 1, rollsTail)
        case first :: second :: rollsTail // normal
          => scoreRecursive(currentScore + (rolls take (2) sum), f + 1, rollsTail)
        case last :: rollsTail // partial frame
          => currentScore + last
        case nil // partial game
          => currentScore
      }
    }
  }
}

As I described in my previous post (link), the variable rolls might indicate that the above code could be made more functional by replacing it with some other construct like list comprehension or recursion. However, thinking about it, it sort of makes sense since the rolls are indeed what changes as a game progresses. I couldn’t come up with a more functional implementation that is not less expressive. Can you?

How to make your Scala code less imperative and more functional

Atlantis StartWhen first starting out with Scala after programming in Java for many years chances are you are still writing Java code just in Scala syntax. Meaning you are not leveraging all the functional goodness that is Scala. Functional code is usually more concise and can be more expressive than imperative code, because functional language constructs operate on a higher level of abstraction than your ordinary execution path loop and fork. It is more about saying what you want and less about how you want it done.

I found the following actions helpful in my quest to make my Scala code less imperative and more functional:

  • Try to eliminate variables and loops by replacing them with list comprehensions and recursion.
  • Try to eliminate if statements by replacing them with pattern matching.

Basically, I look for the key words ‘var’, ‘for’, ‘while’ and ‘if’ in my code and try to think up a way to replace them with something more functional. The result is usually not obvious (for non-(not yet)-functional programmers that is anyway), but I tend to like it more than what I had before.

Question everything you do

Question everythingI realized that I follow a certain plan of attack when confronted with a task. I ask myself the following questions:

  1. Why am I doing this?
    The first thing I do is to ask myself why I am carrying out the given task. This is mostly about trying to understand the task and the problem it tries to solve.
  2. Am I solving the right problem?
    Once I understand the task and the problem at hand, I think about if the problem is the real issue that needs to be solved or if it’s just a symptom of an underlying issue.
  3. Can I do this a better way?
    When I am convinced that I am working on the right problem I try to come up with a better way of solving it. To answer this question I need to use my (and/or my collegues’) experience from having solved similar problems before.
  4. Can I automate this?
    After solving the problem with the chosen solution and given this is a reoccuring task, I think about how to automate the task as much as reasonable. Determining if (or to what extent) the automation is reasonable includes meassuring up the time it takes to automate the task against 

    • the (total and manual labor) time savings by (partially) automating the task
    • the number of times and the frequency the task needs to be carried out
    • the error-proneness of the task
    • the impact of mistakes when carrying out the task

    The higher the values for these items the more likely I am to automate.

Extracting a mantra out of the above steps, my suggestion to you would be: Question everything you do. Never just mindlessly agree, especially if it has always been done ‘this way’. In my experience this is more often an indication that it is done wrong rather than proofing that it is the right way to do something. Never stop challenging the status quo.

But why?

Why, you ask? Good that’s what I am talking about. Questioning what you are doing and how you are doing it is the only way to improve. This is what agile and lean practices like retrospectives, 5 Whys and root cause analysis are based on.

Image by Cyndy

How to make changes to rotten legacy code

Rotten appleWouldn’t it be great to start a project from scratch? Use all the latest technologies, design and write the software TDD-style, as the creator intended? Well… yes, but this isn’t your dream world, this is reality. And here we have to deal with existing software (aka legacy software) most of the time. Unfortunately, this software usually doesn’t have an extensive test suite that allows it to be refactored with every change. More often than not programmers take great care not to touch any existing code when adding new functionality or fixing a bug in order not to risk breaking any functionality. This, of course, is to the disadvantage of design and maintainability. And so software rots, a little bit with every change. The more rotten it is, the harder it is to bring it back on track and clean it up again.

What to do?

So, what are you supposed to do? Cleaning it all up is a way too daunting task and would probably take longer than writing the whole thing from scratch again. Management will never agree (for good reason). So, don’t even think about it, it’s not an option (in general, there are of course exceptions). The way to go is to follow the boy scout rule: “Leave the place cleaner than you found it.” If you follow this rule consistently you will clean up the code bit by bit, change by change. And more than that, you will clean up the most important parts first – the parts that change most often. In other words: If it took you x hours to understand the bloody mess, don’t make it x+1 hours for the next poor soul that comes down this track.

How do you do this exactly?

Here’s how I usually attempt making a change to legacy code.

  1. Find the area (class(es), method(s)) you need to change.
  2. While you are trying to understand the code rename variables to more expressive names than ‘m’ and ‘m2′ (resist to change any behaviour just yet).
  3. Once you understand the input and output of the area you need to change, write (unit) tests that cover the existing behaviour. This might be hard since code developed non-TDD-style tends to be not easily testable. Try anyway.
  4. Once you got sufficient code coverage, refactor the hell out of the code to transform it into a better design and make it more understandable (e.g. every comment is an invitation to extract a method with a name conveying the message of the comment.) It is of course debatable what sufficient code coverage is. For me it means that I am comfortable with making changes to the code without worrying about breaking existing functionality.
  5. Write a failing (unit) test that uncovers the bug you are fixing (bugfixes without tests are anti-fixes) or the missing functionality you are adding.
  6. Fix the bug/add the new functionality.
  7. Feel good about yourself.
  8. Make sure everybody on the team agrees upon making an effort to not letting code rot and that their is a common standard of code quality. This is probably the harder part. I am still working this one out myself.
  9. Life happily ever after
Image Wikipedia

Distributed CI: How it could work

I think distributed CI is the logical next step in the evolution of Continuous Integration by getting rid of the manual step of running a private build on the developer machine before committing to the master repository. Here is how I imagine this might work.

  • Managers, developers and customers (or all stakeholders if you will) collaborate via a wiki and issue tracking tool. These two components tend to be heavily intertwined and are often realized within a single tool. Project management is happening in this area as well.
  • Developers can access the tasks in the issue tracker from within their development environment (IDE).
  • While programming, quality assurance plugins inside the IDE point out potential bugs or design flaws to the developers using the same metrics as are measured by the quality analysis run by the central CI server.
  • Whenever the system is in a consistent state developers commit their changes to their local clone of the Version Control System (VCS) repository. This should happen fairly frequently; several times a day. If you don’t commit frequently you are not doing continuous integration. (side note: The VCS should contain everything that is needed to produce the system from scratch, including database scripts, operating system setup (aka infrastructure as code), etc. – everything.)
  • The local Continuous Integration (CI) tool notices the changes in the VCS repository, gets the latest changes from the master repository and kicks off a build of the changed code module. The build also runs a suite of unit tests to make sure the changes haven’t broken any existing code.

DCI - central server

  • After successfully building (and testing) the code the build tool stores the created artefacts in a repository manager. Note: I believe build artefacts don’t belong in your VCS for several reasons. You shouldn’t have to store them there either, because you should be able to recreate them from any version in your VCS. But there are also reasons why it might not even be a good idea to do so. Most importantly, it makes traceability harder. For each artefact I want to know which version of my source was used to build it. If build artefacts are stored in VCS as well and therefore create new versions themselves, this becomes harder. Also, all these snapshot versions that are produced many times a day, of which some might even break the build are not worth the disk space they occupy.
  • Once the local commit build is successfully run and the snapshot artefacts stored in a repository manager the local CI tool pushes the changes to the master repository.
  • Similar to what happened on the developer machine the central CI tool picks up the changes and runs a commit build. The produced artefact becomes a release candidate with a new version number and is stored in the repository manager, where it can be attained by later phases. (The maven-release-plugin is a great tool to automate this.)
  • The produced artefacts are then automatically deployed to a test environment. The deployment tool gets the artefacts from the repository manager and deploys them on a test environment.
  • There automated acceptance tests are run by the CI tool. If these acceptance tests are successful the tested artefacts are promoted to enter the last phase in your deployment pipeline – deployment to production. It is important to note that only the commit build phase produces new artefacts. All following phases are re-using these artefacts. An example on how to configure Maven not to rebuild the artefacts in later phases can be found here. Your own deployment pipeline may include more phases than just these two. For instance a manual test phase or performance test phase. Usually these can be performed in parallel and therefore require separate environments (hint: virtual machines are of great help here, but that’s a topic for another post).
  • Deployment to production either happens automatically, if you are practicing continuous deployment (good on you), or by manually deploying from your CI server. Even if done manually this should only require the click of a button and should only be possible for artefacts that have successfully completed the previous phases in your deployment pipeline.
  • Periodically the central CI tool runs a code quality analysis tool, which measures code quality by analysing code coverage and other metrics. Discovered violations can be accessed and fixed directly within the IDE.
  • The IDE, the VCS, the CI and code quality analysis tool all feed information back to the issue tracking tool to provide a complete picture of the status of a tracked task.
  • Automated monitoring keeps an eye on the system while it is running in the target environments. This monitoring can also be utilized during automated deployments to decide if a deployment was successful or needs to be backed out. It is mostly agreed upon that the monitor should check business metrics rather than technical aspects.

You can find the entire diagram in animated form here.

Here are my favorite tools for the above process:

  • Wiki: Confluence
  • Issue Tracking and Project Management: Jira
  • IDE: Eclipse (with Mylyn for Jira issue/task integration and Sonar IDE to see all the technical debt right in your IDE where you need it the most)
  • VCS: Git/Mercurial (I am undecided on this one)
  • Build: Maven
  • CI: Hudson (soon to be Jenkins)
  • Repository Manager: Nexus
  • Quality Analysis: Sonar
  • Deployment: Cargo (for deploying to an application server) + Vagrant/Puppet (for creating, provisioning and managing environments)
  • Monitoring: Splunk

Follow

Get every new post delivered to your Inbox.