Software developer blog

On the first day of NDC London 2013 there was a cage match between Gary Bernhardt of Destroy All Software – known for the WAT talk, and Useing You’re Type’s Good – and Jon Skeet of Google – known for his “C# in Depth” book, and his activity on Stack Overflow. They were discussing the topic of dynamic versus static typing.

Jon Skeet started by asking, what is it that Ruby can do and C# can’t. In response Gary tried to show stuff that seems idiomatic in Ruby, and relies heavily on the dynamic nature of Ruby. Where the discussion went a bit south was when Jon Skeet tried to do all that in C#, and did the ugliest hacks just to make it work, while relying on C# features that are explicitly there to make C# a bit more similar to dynamically typed languages. All that proves to me, is that C# is trying really hard to be Ruby, and sucks at it. So what? Besides, we all know that it’s not true at all.

I personally have changed back and forth between statically typed and dynamically typed languages quite a lot, and both hated and loved them every time I did. After a while I started to have very exciting discussions between the left and right side of my brain. (Rest assured: we are not schizophrenic, although the rest of this blog entry may suggest differently.) The odd thing is that both of me seem to have realized that the other has interesting points to support his beliefs, but neither of me is willing to give up any of it. Instead I kind of became the devil’s advocate on the matter. (And that’s really funny if you know what my last name – Ördög – means in Hungarian.) Whenever I meet anyone who seems to strongly believe in one or the other, I try my best to convince them that they are completely wrong and total idiots. So if you came here with the intention of finding out which one is better, here is a final clue: you won’t! However I promise there is an interesting conclusion at the end.

Let’s give a name to my brains, just to make the rest more fun: Steve is a firm believer in static typing, while Dan is this ruby / nodejs fan boy.

If you wish to read a transcript of the video click here.
@ //

Last Saturday we had the first ever Lean Poker Tournament, an event much like a code retreat, but with a slightly different format and purpose. A lean poker tournament’s aim is for participants to practice concepts related to lean start ups and continuous deployment. A poker team is a small group of developers (ideally 4 people forming 2 pairs) whose aim is to incrementally build a highly heuristic algorithm within a one day time frame that is just smart enough to beat the other robots. Professional poker robots are developed for years, so the purpose is definitely not to come up with something really smart, but to be the smartest among the current competitors. With this in mind teams can come up with simple to implement heuristics, examine their effect on game play during training rounds, and then improve their algorithm in a similar lean fashion.

The participants of the very first Lean Poker Tournament.

The participants of the very first Lean Poker Tournament.

@ //

Few weeks ago we held an internal Coderetreat at Emarsys for all programmers within the company. When the business intelligence team heard about it they started to joke around, that they should drop by and implement Conway’s Game of Life in SQL. I’m not much of an SQL wizard, but I rose to the challenge. First I tried it in MySQL, since that’s the dialect I have the most experience with:

CREATE TABLE generations (`id` INT UNSIGNED, `x` BIGINT, `y` BIGINT);
INSERT INTO generations VALUES (0, 0, -1), (0, 1, 0), (0, -1, 1), (0, 0, 1), (0, 1, 1);
 
CREATE TABLE offsets (`x` BIGINT, `y` BIGINT);
INSERT INTO offsets VALUES (-1,-1),(-1, 0),(-1,1),(0,-1),(0,0),(0,1),(1,-1),(1,0),(1,1);
 
INSERT INTO generations 
  SELECT g.id+1 id, g.x+o.x x, g.y+o.y y
    FROM generations g 
      INNER JOIN offsets o 
    WHERE g.id=(SELECT MAX(id) FROM generations)
    GROUP BY g.x+o.x, g.y+o.y
      HAVING (MAX(o.x=0 AND o.y=0) = 1 AND COUNT(1) - 1 BETWEEN 2 AND 3)
        OR (MAX(o.x=0 AND o.y=0) = 0 AND COUNT(1) = 3);

It works, and it’s not even that complicated. First we join the last population with an offset table to generate the set of living cells and their neighbors. Grouping by the cell coordinates plus the offsets we can get all necessary information. The expression max(o.x=0 and o.y=0) is one exactly if the cell was alive in the previous generation, otherwise it’s zero. Using that we can count the number of neighbors too: count(1)-max(o.x=0 and o.y=0). The having clause utilizes that knowledge to filter the grouped rows to contain only the cells in the next generation.

@ //

This year I have talked at different Hungarian venues about software development related topics several times. Although these presentations are captured on video and are available on the internet they are in Hungarian, so I decided that the next few posts will explore some of them in English, and in more depth.

I gave the Test Driven Mockery talk at the April event of PHP Meetup Budapest. Although code examples and frameworks are in PHP, the talk is basically language agnostic, and it’s just as useful for PHP programmers as it is for Java, C#, Ruby or even C++ coders. After all: it’s about test doubles in general.

At the time of writing this blog entry more and more software developers and companies decide to adapt test driven development as one of their primary practices to avoid code rot and fear of change. Of course there are crowds who still haven’t even tried TDD either because they haven’t heard about it, or it sounded too weird for them to try. However there is another lot more interesting group of educated professionals who after practicing TDD for a considerable amount of time decide to abandon it. As I was talking with a group of these people I recognized that most of the time their disappointment in the technique is easily tracked back to their misunderstanding of a very important related topic: test doubles and mocking. On one hand if you completely avoid using them you end up with a slow and fragile test suite that’s hard to maintain, but if you use too many of them the promise of ease of change, well tested and flexible code becomes a lie. Finding a good balance is kind of an art.

A lot has been said about good and bad design decisions all over the web, and I hardly think I could add anything new to the list of code smells. Yet they still keep popping up in every single piece of legacy code I come across. My theory is that many of these patterns do not simply arise as the evil doings of a single bad programer, but more as a result of collaboration between brilliant programers, who just fail to realize the problem early. If you look at it that way it becomes apparent that bad designs are inevitable in the long run, and so eventually they need to be fixed.

Or do they? Well… it all depends of course. There is nothing more harmful than putting countless hours of work into changing code for the sole purpose of aesthetics. I’m an idealist at heart, and I’d love to spend all the time I can find on prettifying the existing code base before I ever change behaviour, but the reality is that beautiful code won’t earn you a single penny unless it delivers business value. On the other hand we all know that bad code can hurt us big time: not only makes it expensive to add behaviour, it also gets hard just to keep things from falling apart.

Refactoring legacy

Refactoring code without tests feels like tightrope walking for the first time.

Are you confused yet? Should you refactor or even rewrite that piece of ugly spaghetti code tomorrow morning, or not? Let’s say that by default you should never touch legacy code that works as expected. (It gives me enormous pain to even think that this is a good idea…)  Accepting the premise here is a list of the most important exceptions to this rule, when you should most definitely become obsessed with cleaning your code.

@ //

Yesterday we held our first Legacy Codereatreat in Budapest. While it is very similar in concept to regular Coderetreats, there are some very important differences. We start the day by introducing an existing legacy code base – a rather ugly one – and let the pairs figure out what it does. Yesterday we’ve been using the trivia code base on GitHub, so that participants could choose from a large variety of languages, but still have approximately the same code base.

Legacy coderetreaters at Emarsys Technologies Ltd., Budapest

Legacy coderetreaters at Emarsys Technologies Ltd., Budapest

According to Michael Feathers’ definition of legacy code: “it is code without tests”. So after the first getting to know session the next session was about adding characterization tests to the code that would help us during the remaining sessions. Since the only UI to the application are log messages, but they are scattered all around the code base, it is a relatively safe test suit to generate runs with random inputs, and save the output for reference. It won’t help in figuring out where the error is, but it will catch most of the mistakes one makes during refactoring. They can also help when adding behaviour, but when fixing bugs they will brake, and need to be replaced.

@ //

Facebook used to have this awesome list of programming puzzles that were freely available. One of them was peak-traffic, which can be rephrased as the maximal cliques problem pretty easily. Unfortunately a graph can have exponential number of maximal cliques, so it’s not surprising that we can not find a polynomial algorithm for listing all possible maximal cliques in a graph. However there are output sensitive algorithms: as long as the number of maximal cliques is relatively low each can be reported in a short time.

A complete sub-graph of a graph is called a clique, much like we call a group of friends a clique if they all know each other.

I knew that I was looking for such an algorithm, but it was kind of hard to find a detailed enough description on the Internet.  At the time of writing Wikipedia does provide a short description of the algorithm devised by Tsukiyama et al. but there are a number of details omitted, making it kind of hard to come up with the right implementation.

My aim is to provide a simple to understand description of the algorithm (without proof that it works correctly) and share my implementation in C++. (Type `make smoke` to compile and test.) The source I’ve been using – apart from Wikipedia – was a 2004 paper written by Kazuhisa Makino and Takeaki Uno: New Algorithms for Enumerating All Maximal Cliques.

Last week I have attended a free conference in Budapest themed around web development. Here is a quick recap. Unfortunately the conference was held in Hungarian, so most of the resources I link to are in Hungarian.

János Pásztor described how they built up the infrastructure for a tiny start up called neticle.hu. His talk was recorded on video, and a short lecture note is available. It’s a very good starting point, and contains a lot of information on tooling. The most important part for me was where he talked about configuration management: with the right tooling it can become almost automatic to add a new server to your system. Definitely worth a bookmark if you plan to start your own web based service some time in the future.

László Merklik talked about test driven JavaScript development. His point was that although one is tempted to believe that we only write the user interface in JavaScript, usually a lot more logic ends up on client side than we have bargained for. Having a decent test suite for JavaScript not only helps in developing the client side code as it does in other languages. It also provides an easy and automated checking mechanism for compatibility with any number of browsers, a challenge that doesn’t even make sense in other languages.

@ //

About 9 month ago as we were preparing for the next Coderetreat Athos came up with an idea for a game he called the changing requirements. I liked the idea from the get go, since I think that in becoming a software developer the hard part is learning how to react to business needs. At least for me that took a lot more time than to write my very first game in QBasic as a little kid.  The really sad part is that one can graduate university without ever even realizing that he is missing one of the software craftsmens most important virtues.

What I found really appealing in the concept of Coderetreats was that it provided a forum for professionals to learn about techniques that can help in dealing with change. On the other hand it is about getting away from the pressure of getting it done, and by that it takes these techniques out of context. It’s kind of the price for letting you concentrate on practice.

The changing requirements game is something we like to play as the very last session of a Coderetreat. By that time the participants have learned a lot of new things, and have become familiar with game of life. The session is 90 minutes long  – enough time for a pair to finish the job – but we come up with requirement changes at times when it’s already too late to incorporate that into the design without substantial refactoring. If the pair has already learned how to do evolutionary design they will easily adapt, otherwise they will have quite a bad time. Either way they will hate the facilitator for a second, and then they will get really excited about the problem.

Last week we had our 4th Coderetreat in Budapest with about 15 participants. This time I was an organizer along with Athos, and we decided to advertise the event at several different meetups. While preparing slides for the talks we realized that on one of the slides we had some free space we could not really fill… so we came up with the idea of putting an image macro there. And that’s how Uncle Bane was born:

Uncle Bob will probably approve this message…

That kind of unleashed an entire flow of crazy meme ideas, so I decided to popularize the Coderetreat event by posting these memes on the groups Facebook page. (Check them here.) The meme that turned out to be the most successful was this one:

Stare dad

That’s exactly how I’d react…

Next Page »

Switch to our mobile site