So I participated in the 48 hour Node.js Knockout competition together with James Halliday and Joshua Holbrook. Our team was called Dark Knights and we created an online chess application called Node Chess.

We didn't quite manage to completely finish the game and it has several bugs, like the turns don't alternate and the king can be captured, but it's crazy awesome anyway. If both players follow the rules, it all works correctly. Castling works, pawn promotion works, capture en-passant also. Try it and if you find it awesome, please vote! Oh, and it works only in Chrome. We were under time pressure and at one point it stopped working under Firefox and we did not get to fixing it.

Here is how the game looks,


A chess game between pkrumins and someone. King's Indian Defence.

Joshua did all the awesome vector graphics work. I did the chess engine work, and James used his amazing dnode node.js module to blend client and server code together. James has actually redefined how web development happens. Instead of writing server code and client code, as we are so used to, with his dnode framework it's now possible to use the same code both server and client side! Much less hustle and purely ingenious!

Here is the same game in perspective view, the highlighted squares are the available moves,


The same game in perspective view.

And the moves are animated, too! The pawns shoot the opponent pieces and the queen stabs them. Try it!

Right, so my reflections on the competition.

It was well organized, and we were sent access to a Joyent deployment server and a Heroku server early on together with instructions. It turned out that Heroku's didn't support Socket.IO or websockets. Win for Joyent. Pretty much everyone went with Joyent as far as I know. We had some technical difficulties at the start with deploying our code, but guys at #node.js helped us and we got our app running pretty quickly.

We used 3 Git repositories to push the code to, our own GitHub repositories (pkrumins, substack, jesusabdullah), then the node knockout's private repository for judges, and deployment repository on Joyent. Joyent was configured so that as you push your code to its Git repo, the hooks in it would restart the node.js service and the you'd be instantly running the latest version of your code.

So I'd make changes push to my GitHub repo, James would pull from me. He'd make changes, I'd pull from him, and same for Joshua. It went pretty flawless. We had like 12 merge errors total, but those were all resolved within a minute or two.

Now some numbers. We're actually amazed by our performance. Check out these numbers:

$ git log | grep Author | wc -l
429

429 commits! Can you believe that? 429 commits in 2 days! That's 9 commits per hour on average! That is what I call hacking!

My commits:

$ git log | grep Author | grep Peteris | wc -l
169

I did 3.5 commits per hour on average. And funnily, James and Joshua each had 130 commits:

$ git log | grep Author | grep James | wc -l
130
$ git log | grep Author | grep Joshua | wc -l
130

That's 2.7 commits per hour on average! Amazing! But we also slept between the competition days. On the both days we did about 4 hours of clean sleep, shrinking our competition time to 40 hours. Then our average becomes 10.7 commits per hour! Wowsers!

Here is a graph, made with Raphael.js, that shows our git commit activity by hour, starting from 3am UTC Aug 28 to 3am UTC Aug 30:


Team "Dark Knights" git commit activity by hour.

Our peak commit intensity was at 9pm the last night, when we did 23 commits in one hour. Our team was also widely spread out. I am in Riga, Latvia, James is in Kenai, Alaska, and Joshua is in Fairbanks, Alaska. Yet we managed to keep the same schedule. I'd go to bed at noon (noon for me is 3pm UTC, see the graph above), while James and Joshua at midnight, and we'd wake up several hours later and keep hacking!

Total number of code lines written:

$ wc -l `find . -name '*.js' -o -name '*.html' -o -name '*.css' | \
  egrep -v '(jquery|raphael)'`
3074 total

So we wrote 3074 lines in two days, which according to git break up into added vs. deleted as following:

$ git log --numstat | grep '^[0-9]' | \
  egrep '(\.js|\.css|\.html|jquery|raphael)' | \
  awk '{a+=$1;d+=$2}END{print "Added: " a, "Deleted: " d}'
Added: 5210 Deleted: 2042

Hmm, 5210-2042 doesn't quite add up to 3074 but is close enough. From these 3074 lines of code non-empty were:

$ cat `find . -name '*.js' -o -name '*.html' -o -name '*.css' | \
  egrep -v '(jquery|raphael)'` | perl -nle 'print if /\S/' | \
  wc -l
2659

So 2659 real lines of code in 2 days! Talk about productivity! And that's just code alone. Joshua also did 50 artworks,

$ find . -name '*.svg' -o -name '*.png' | wc -l
50

Total number of file changes:

$ git log --shortstat | grep 'files changed' | \
  awk '{t+=$1}END{print t}'  
724

We communicated in IRC, in our #stackvm startup channel. Here are some statistics on how much stuff went on in our IRC channel:

$ (
  grep -v '^0[012]:' '#stackvm.08-28.log';
  cat '#stackvm.08-29.log';
  grep '^0[012]' '#stackvm.08-30.log'
  ) | wc -l
5069

So 5069 events happened during the challenge. That's 105 events per hour on average. We have a special lulbot in it who tells us when we commit, for example:

05:59 < lulzbot-X> Whoa Nelly! New commits to pkrumins/node-chess (master)!
05:59 < lulzbot-X>     * Peteris Krumins: MoveGenerator stub
05:59 < lulzbot-X>     * Peteris Krumins: abstract pieces
05:59 < lulzbot-X> githubs: http://github.com/pkrumins/node-chess/tree/master

Here lulzbot informed us that I committed MoveGenerator stub and abstracted pieces in node-chess repo.

Out of these 5069 events, we talked this much,

$ (
  grep -v '^0[012]:' '#stackvm.08-28.log';
  cat '#stackvm.08-29.log';
  grep '^0[012]' '#stackvm.08-30.log'
  ) | egrep -i '^< pkrumins|substack|jesus' | wc -l
2682

So we spoke 2682 times or 83.8 times per hour. We also asked quite a lot questions:

$ (
  grep -v '^0[012]:' '#stackvm.08-28.log';
  cat '#stackvm.08-29.log';
  grep '^0[012]' '#stackvm.08-30.log';
  ) | grep '?$' | wc -l
246

246 questions, for example (random selection):

< pkrumins> wait, are we including a version of socket.io.js in dnode?
< jesusabdullah> but: simplified pieces for thumbs--yea or nay?
< pkrumins> is anyone working ont he problem where the opponent cant make moves?
< SubStack> pkrumins did you see how I just dumped the node EventEmitter code into our lib/?
< SubStack> does S create a row?
< jesusabdullah> pkrumins: You fixing the board?
< pkrumins> how does resizing in raphael happen?

My chess code wasn't the easiest to write and to make sure it works correctly, I wrote 52 expresso tests,

$ expresso 

   100% 52 tests

Without tests I would have never got that chess code right.

That's about it. The competition was awesome, A++ would participate again. Hope they organize node.js knockout the next year, too!

I hope you enjoyed my post and don't forget to vote for our project! Your vote is so important to us. Thank you!

Hey everyone. We at StackVM just finished recording the 2nd demo video. The 2nd video shows all the cool new features we have recently built - user login system, chatting and sharing of virtual machines by just dragging and dropping. Also this time James Halliday joins me from Fairbanks, Alaska!

Here is the video #2,

StackVM brings virtual machines to the web. Join #stackvm on FreeNode to discuss!

If you haven't seen the first video, see my StackVM startup announcement post!

During the past few weeks we have also written two new node.js libraries for use at StackVM:

We did not demo gifcasts in this video but I am going to do a separate video in the next week or two showing just that. They're pretty awesome!

In a few weeks we'll also post the 3rd demo video. In that video we have planned to show virtual network editor that allows to network virtual machines by just dragging and dropping! Be sure to subscribe to catonmat's rss feed and follow me on twitter to know when the video is out!

See you!

Ps. Join #stackvm on FreeNode to discuss StackVM with me and James! We're there 24/7!

Hey everyone,

I have exceptional news - I am doing a startup together with James Halliday!

I met James on FreeNode several years ago and it turned out that we had very similar ideas about doing great hacking. So we teamed up as equal co-founders to do a startup. We're on different continents but we use IRC, GitHub and WeDoist to get stuff done!

Check out an early demo of our software:

StackVM brings virtual machines to the web. Join #stackvm on FreeNode to discuss!

The startup we're doing is called StackVM. StackVM makes virtual machines much more accessible over the web, makes them easier to use, and makes them embeddable in webpages (like putting a virtual machine in a blog post). This is just the first step that we're starting with. Next we're making networking between them very easy, just drag and drop to create any virtual network topology you wish, with firewalls, switches, etc. (fun for hacking competitions and learning networking). Then we're making what we call "vmcasts" - much like a screencasts, except the computation is recorded, meaning that at any point you can break into the playing vmcast and change the course of computation (and return back to it later).

Our plan is to host the virtual machines and our awesome software for you, so that you don't have to worry about anything. We'll make sure it all works! At the moment we're actually already at our third major iteration of the software.

Here are a few use cases:

  • Suppose you're selling software and you want your users to try it before they buy it. Perfect use of StackVM - put your software in the virtual machine and embed it on your products page. The potential customers can try your software before they buy it right from your website!
  • Suppose you're an application developer and have written a program that should work cross-platform. You can easily rent 10 virtual machines with Linux, Windows, MacOS, and other operating systems and test your software. Just drag and drop it into the virtual machines, and you can test your software!
  • Suppose you want to teach someone how to work in Perl in a series of blog posts (like I do), you can embed the terminal with a vmcast in your blog post, and everyone can follow your tutorial, and also try out the examples interactively, in a real shell!
  • You can build a virtual honeypot network and have hackers break into it, then analyse how they did breakins. Or, you can build a huge network and learn routing and networking concepts!
  • Suppose you want to share your work with a group of people. You can easily do it in stackvm! Just send the other people link to your VM and they can connect to it with any web browser. They'll be able to see what you're doing, comment on your work, and if you allow fix your bugs (think pair programming!)

Hosting virtual machines requires a lot of infrastructure, so we plan to start collecting revenue as soon as possible with affordable paid user accounts. We're not going to do the common nonsense among startups of first building up the project for years and only then trying to figure out how to make it profitable. We're going to offer virtual machines together with an awesome interface and features to them as a monthly paid service from the day we launch. We're also going to have an open API to our software, so that you can build on top of it or customize it (for example script virtual machines to do something specific).

We're also testing out the idea of complete openness with this startup. It's going to be 100% open-source and 100% idea-open, meaning that anyone can read what we're up to, and run our code if they want to run stackvm on their own. So far we have shared all the code on github (my stackvm repo, James's stackvm repo) and documented most of the ideas and experiments on stackvm github wiki.

We're applying for YC funding later this year so that we can focus on hacking and not paperwork.

Now a little bit about the tech we use at StackVM. I won't go into much details right now because many of the future posts will detail the tech at StackVM.

At the moment StackVM is in its 3rd major iteration already and is almost entirely built on node.js. Since we're doing everything open-source, we've written a bunch of reusable node.js modules:

  • dnode - Simple asynchronous remote method invocation for node.js.
  • node-bufferlist - Abstraction of node.js's buffers and monadic binary parsing.
  • node-rfb - Implements the client-side of the RFB protocol that VNC uses.
  • node-png - Produces PNG images from RGB or RGBA values.
  • node-jpeg - Produces JPEG images from RGB or RGBA values.
  • node-video - Records Theora/Ogg videos from RGB values.
  • node-base64 - Encodes binary data to base64 to send across websockets and ajax.
  • node-jsmin - Minify JavaScript on the server side, before sending it to the browser.
  • node-bufferdiff - A module to compare two buffers quickly.

I'll keep everyone updated on the progress and technical insight into our development. If you're not yet subscribed to my posts, please do it - catonmat rss feed. Going to make this happen!

And if you wish to talk about our software, come join #stackvm on FreeNode!

A Year of BloggingHey everyone! Another year has passed and it's now 3 years since I've been blogging here on catonmat! In this post I wish to summarize this year's statistics.

See the one year of blogging and two years of blogging for previous year statistics.

First of all traffic statistics,


Traffic statistics for the period 2009-07-01 - 2010-07-01 from Google Analytics.

Alright, so catonmat has received 1.43 million visitors and 2.11 million page views during this year. That's 120k visits and 175k page views per month. Or 4,000 visitors per day and 5,800 page views per day. Good numbers.

Let's look at the whole traffic picture from the day one of blogging,


Traffic statistics for the period 2007-07-01 - 2010-07-01 from Google Analytics.

Looks pretty random but seems to have a hidden linear trend upwards.

Now the FeedBurner subscriber stats,


Feedburner statistics for the period 2009-07-01 - 2010-07-01.

Last year I left off with 7000 subscribers, and now I have around 12,000. That's 5000 new subscribers, or 13 new subscribers per day on average.

And the whole picture of subscriber dynamics since the beginning of blogging,


Feedburner statistics for the period 2007-07-01 - 2010-07-01.

Also a nice positive trend, if it keeps going the same way, I expect to have around 17,000 subscribers the next year.

Now to articles. During this year I have written 43 articles. Here are ten most popular ones:

Here are my personal favorites that didn't make it into top ten:

It's now time for delicious cake:

Let's meet for cake the next year again! See you!

When people talk about polymorphism in C++ they usually mean the thing of using a derived class through the base class pointer or reference, which is called subtype polymorphism. But they often forget that there are all kinds of other polymorphisms in C++, such as parametric polymorphism, ad-hoc polymorphism and coercion polymorphism.

These polymorphisms also go by different names in C++,

  • Subtype polymorphism is also known as runtime polymorphism.
  • Parametric polymorphism is also known as compile-time polymorphism.
  • Ad-hoc polymorphism is also known as overloading.
  • Coercion is also known as (implicit or explicit) casting.

In this article I'll illustrate all the polymorphisms through examples in C++ language and also give insight on why they have various other names.

Subtype Polymorphism (Runtime Polymorphism)

Subtype polymorphism is what everyone understands when they say "polymorphism" in C++. It's the ability to use derived classes through base class pointers and references.

Here is an example. Suppose you have various cats like these felines,

Polymorphic Cats
Polymorphic cats on a mat by James Halliday.

Since they are all of Felidae biological family, and they all should be able to meow, they can be represented as classes inheriting from Felid base class and overriding the meow pure virtual function,

// file cats.h

class Felid {
public:
 virtual void meow() = 0;
};

class Cat : public Felid {
public:
 void meow() { std::cout << "Meowing like a regular cat! meow!\n"; }
};

class Tiger : public Felid {
public:
 void meow() { std::cout << "Meowing like a tiger! MREOWWW!\n"; }
};

class Ocelot : public Felid {
public:
 void meow() { std::cout << "Meowing like an ocelot! mews!\n"; }
};

Now the main program can use Cat, Tiger and Ocelot interchangeably through Felid (base class) pointer,

#include <iostream>
#include "cats.h"

void do_meowing(Felid *cat) {
 cat->meow();
}

int main() {
 Cat cat;
 Tiger tiger;
 Ocelot ocelot;

 do_meowing(&cat);
 do_meowing(&tiger);
 do_meowing(&ocelot);
}

Here the main program passes pointers to cat, tiger and ocelot to do_meowing function that expects a pointer to Felid. Since they are all Felids, the program calls the right meow function for each felid and the output is:

Meowing like a regular cat! meow!
Meowing like a tiger! MREOWWW!
Meowing like an ocelot! mews!

Subtype polymorphism is also called runtime polymorphism for a good reason. The resolution of polymorphic function calls happens at runtime through an indirection via the virtual table. Another way of explaining this is that compiler does not locate the address of the function to be called at compile-time, instead when the program is run, the function is called by dereferencing the right pointer in the virtual table.

In type theory it's also known as inclusion polymorphism.

Parametric Polymorphism (Compile-Time Polymorphism)

Parametric polymorphism provides a means to execute the same code for any type. In C++ parametric polymorphism is implemented via templates.

One of the simplest examples is a generic max function that finds maximum of two of its arguments,

#include <iostream>
#include <string>

template <class T>
T max(T a, T b) {
 return a > b ? a : b;
}

int main() {
 std::cout << ::max(9, 5) << std::endl;     // 9

 std::string foo("foo"), bar("bar");
 std::cout << ::max(foo, bar) << std::endl; // "foo"
}

Here the max function is polymorphic on type T. Note, however, that it doesn't work on pointer types because comparing pointers compares the memory locations and not the contents. To get it working for pointers you'd have to specialize the template for pointer types and that would no longer be parametric polymorphism but would be ad-hoc polymorphism.

Since parametric polymorphism happens at compile time, it's also called compile-time polymorphism.

Ad-hoc Polymorphism (Overloading)

Ad-hoc polymorphism allows functions with the same name act differently for each type. For example, given two ints and the + operator, it adds them together. Given two std::strings it concatenates them together. This is called overloading.

Here is a concrete example that implements function add for ints and strings,

#include <iostream>
#include <string>

int add(int a, int b) {
 return a + b;
}

std::string add(const char *a, const char *b) {
 std::string result(a);
 result += b;
 return result;
}

int main() {
 std::cout << add(5, 9) << std::endl;
 std::cout << add("hello ", "world") << std::endl;
}

Ad-hoc polymorphism also appears in C++ if you specialize templates. Returning to the previous example about max function, here is how you'd write a max for two char *,

template <>
const char *max(const char *a, const char *b) {
 return strcmp(a, b) > 0 ? a : b;
}

Now you can call ::max("foo", "bar") to find maximum of strings "foo" and "bar".

Coercion Polymorphism (Casting)

Coercion happens when an object or a primitive is cast into another object type or primitive type. For example,

float b = 6; // int gets promoted (cast) to float implicitly
int a = 9.99 // float gets demoted to int implicitly

Explicit casting happens when you use C's type-casting expressions, such as (unsigned int *) or (int) or C++'s static_cast, const_cast, reinterpret_cast, or dynamic_cast.

Coercion also happens if the constructor of a class isn't explicit, for example,

#include <iostream>

class A {
 int foo;
public:
 A(int ffoo) : foo(ffoo) {}
 void giggidy() { std::cout << foo << std::endl; }
};

void moo(A a) {
 a.giggidy();
}

int main() {
 moo(55);     // prints 55
}

If you made the constructor of A explicit, that would no longer be possible. It's always a good idea to make your constructors explicit to avoid accidental conversions.

Also if a class defines conversion operator for type T, then it can be used anywhere where type T is expected.

For example,

class CrazyInt {
 int v;
public:
 CrazyInt(int i) : v(i) {}
 operator int() const { return v; } // conversion from CrazyInt to int
};

The CrazyInt defines a conversion operator to type int. Now if we had a function, let's say, print_int that took int as an argument, we could also pass it an object of type CrazyInt,

#include <iostream>

void print_int(int a) {
 std::cout << a << std::endl;
}

int main() {
 CrazyInt b = 55;
 print_int(999);    // prints 999
 print_int(b);      // prints 55
}

Subtype polymorphism that I discussed earlier is actually also coercion polymorphism because the derived class gets converted into base class type.

Have Fun!

Have fun with all the new knowledge about polymorphism!