The it-agile Startup March: Lessons learned

bart_simpson_chalkboardThis last month six colleagues and I carried out a little experiment: the ‘Startup March‘. We decided that instead of doing development, training, and consulting for our customers, we would dedicate all of our time to work on an idea for a startup. We wanted to put the ‘Lean Startup’  method, as made popular by Eric Ries’ book, to the test. Here’s a list of learnings we came up with and my personal interpretation of them:

  • Co-location: Communication gets orders of magnitude more difficult when a team is distributed. In the early days of a startup there is plenty to talk and to argue about. Not being in the same room will inevitably slow you down. We also found it helpful to be somewhere else than our normal offices, away from all the distractions that would pull us back to the day-to-day duties for our customers.
  • In the beginning focus on individual users: We tried to make informed decisions about our product, depending on statistics, from day one. This is hard, when all of your data is statistically irrelevant. So, we decided to interview people and focus on our early adopters and their needs first.
  • Know your metrics tool(s): Your metrics about your fancy experiments will be useless, if you don’t know what they mean. What is a unique visitor? Someone coming back during the same session? Someone on the same device? Are you counting yourself? If you don’t know this, don’t bother measuring it.
  • Don’t neglect growth: It’s usually more fun to spend time on working on features that create more, but you also need to constantly think about how to get more people to use your tool. In order to do this, you should understand as precisely as possible who your customers are and which problem you are solving for them.
  • A moderator can be helpful: We made all the decisions along the way in the team without having an authority like a Product Owner. In the end we concluded, however, that a moderator like the Scrum Master role would have been helpful during some discussions. This doesn’t have to be the same person all the time, but it might be helpful to have this dedicated role to keep discussions from dragging on longer than they have to.
  • Sync often: Most of the work was done in groups or pairs. To get everyone up to date, we did brief stand-up meetings throughout the day. Usually between two and four of them. With most of the system changing all the time it is important to keep everyone pulling in the same direction.
  • Release more often and know when to clean up: In a startup environment you are optimizing for customer feedback. This is very different to a project that has been going for a couple of years. Clean code is important in the later, not so much in the former. I am not telling you to intentionally write bad code, but to make a conscious decision about the time you invest in cleaning it up. The half life of code in a startup is very short. There is no point in writing the cleanest code you can for an experiment you are going to throw away tomorrow. When some functionality has stuck around long enough and is actually valuable to your users, and you keep breaking it unintentionally, it’s probably time to write some tests and start refactoring it.
  • Explain your features to your users: It may seem obvious to you why and how to use your tool, but it’s not obvious to your users. So, explain features and what value they will provide.
  • Present to an independent audience about your idea early on: We presented our idea and our first findings about Lean Startup after three weeks to an independent audience at an evening event. This forced us to review our results thus far and we received valuable feedback by the participants.
  • Don’t force a process on yourself: If you’ve got a team of experienced people, don’t force yourself to use a specific process. Scrum by the book is intended as a starting point for teams that are stuck. A team that has understood agile values will figure out it’s own process.
  • Decide on the general topic and the techno stack and get to know them ahead of time: If you are planning on doing a similar experiment, where you spend a limited amount of time with some colleagues to work on a startup idea, do yourself a favor and get to know the problem domain and the technology ahead of time. This way you can jump right in on day one. Otherwise, chores like setting up your dev machine and working through a tutorial, will eat up your precious time. BTW, we went with Rails, which was great to get off the ground quickly.
  • Get a designer on the team: Most developers know how to make a piece of software work, very few of them also know how to make it look good. No-one will use your tool if it looks like it was developed in the ’90s.
  • Have a team event early on: It will help your team gel quicker. The work will be more effective and more fun.
  • Team size: There was no agreement on this amongst the team, but I have an assumption that a smaller team would have been more effective. I base this assumption on another assumption that a smaller team would have needed less time for communication, both synchronizing and debating. Others argue that, if we took the four team members with the most oposite opinions it would have taken us just as long to debate and if we took the four team members with the most aligned ideas we would have had less inovation. I still think in the early days of a startup, as long as you got all the necessary skills on the team, a smaller team will outperform a bigger team, because of the frictional losses for synchronizing about all the moving parts.

All in all, for me the focus on experiments to prove one’s assumptions is the most important contribution of Lean Startup to my personal tool box.

Further reading:

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
Follow

Get every new post delivered to your Inbox.

Join 119 other followers