Thursday, June 30, 2011

Rod Johnson on Entrepreneurialism

One thing I think that you really need to be careful of as well, particularly if you, like me, are a programmer, is don’t get carried away writing code. Typically in my experience anyone who is a good programmer is pretty passionate about it, love writing code, get addicted to the process of writing code, fell pretty good about their code basis. As soon as you get down that path you are not thinking straight anymore and now you are increasing your emotional investment, you are having lots of fun writing interesting code and you are no longer in a place mentally where you are going to be trying to find some reason that you shouldn’t write that code. That has been a big lesson for me that the quicker I get to coding, the longer it takes me to ask the kind of questions I should ask upfront.
...
It is really, really hard to decide not to do things. One of the biggest killers of companies is trying to do too much. If you try to take on too many things you will assuredly fail, even if every one of those things is a good thing to do. It is incredibly hard to realize that a particular thing is a good idea, but you are not going to do it.
...
I think the biggest way to decide frankly if you are trading off business priorities is do the boring stuff like, look at the total addressable market, go and talk to customers, figure out what they will pay for. You really need to be guided by what the revenue is likely to be, and make sure you don’t just do something just because it’s cool.

Monday, June 27, 2011

Math and Physics of Benderama

The last episode of Futurama has interesting formula involved. The entire plot is based on the Professor's latest invention — Banach-Tarski Dupla-Shrinker — the machine that produces two copies of any object at a 60% scale. It was just a matter of time when Bender found a good usage of this machine: to replicate himself. Then two small copies of Bender replicated themselves making four smaller copies, and so forth. At some point the Professor horrified the crew that if they don't stop this unlimited growth, the total mass of all Benders will eventually be so big that the entire Earth will be consumed during the process of replication. As a proof he demonstrated this formula of the mass of all generations of Bender


This is a perfect toy for a science geek. The first obvious question it brings: is this formula mathematically correct? As it turns out, it is not. Considering the scale of 60%, the cubic dependency of volume on linear dimension, and the constant density of all copies, the formula should be the following


As you can see the total mass of infinite number of Benders actually converges to approximately 1.76 M0. So from Math perspective there is nothing to worry about. But what if our assumption of constant density is invalid. Would it be a problem from Physics perspective? Let's see.

Knowing that every new copy has a size of 0.6 of the original it was made from, we have the following formula for the size of Bender in the nth generation


This exponential function becomes very small pretty soon. In the 154th generation it already reaches the Planck length, after which the further replication is physically impossible. If we calculate the total mass of 154 Bender's generations using the Professor's formula, we get H(154) × 238 kg ≈ 1,337.56 kg, which is nothing comparing to the Earth mass.

So we have to admit that from both Math and Physics perspective the Professor was wrong, and there was no real threat to the Earth.

Although the Professor's formula doesn't describe the replication process adequately, it's still a beautiful piece of Math because it's a formula of harmonic series. If you want to know why harmonic series is beautiful and which real processes it describes, read this nice article of John H. Webb.

And don't miss the next episode of Futurama this Thursday :-)

Wednesday, June 08, 2011

Functional Groovy switch statement

In the previous post I showed how to replace chained if-else statements in Groovy with one concise switch. It was done for the special case of if-stement where every branch was evaluated using the same condition function. Today I want to make a generalization of that technique by allowing to use different conditionals.

Suppose your code looks like this:

if (param % 2 == 0) {
'even'
} else if (param % 3 == 0) {
'threeven'
} else if (0 < param) {
'positive'
} else {
'negative'
}

As soon as every condition operates on the same parameter, you can replace the entire chain with a switch. In this scenario param becomes a switch parameter and conditions become case parameters of Closure type. The only thing we need to do is to override Closure.isCase() method as I described in the previous post. The safest way to do it is to create a category class:

class CaseCategory {
static boolean isCase(Closure casePredicate, Object switchParameter) {
casePredicate.call switchParameter
}
}

Now we can replace if-statement with the following switch:

use (CaseCategory) {
switch (param) {
case { it % 2 == 0 } : return 'even'
case { it % 3 == 0 } : return 'threeven'
case { 0 < it } : return 'positive'
default : return 'negative'
}
}

We can actually go further and extract in-line closures:

def even = {
it % 2 == 0
}
def threeven = {
it % 3 == 0
}
def positive = {
0 < it
}

After which the code becomes even more readable:

use (CaseCategory) {
switch (param) {
case even : return 'even'
case threeven : return 'threeven'
case positive : return 'positive'
default : return 'negative'
}
}

Tuesday, June 07, 2011

Nothing new under the sun

Every generation of software developers needs its own fad. For my generation it was Agile, for generation before it was OOP, and before that it was another big thing. Gerald Weinberg, one of the most influential people in our industry, blogged yesterday about this issue. With over 50 years of experience in software development he knows what he is talking about. Read his blog post — he has a very good point.

P.S. I'm wondering what will be the next big thing. Will it be Cloud or Big Data?

Sunday, June 05, 2011

Multimethods in Groovy

Every time I switch from Groovy to Java I have to remind myself that some things that seem so natural and work as expected in Groovy, don't work in Java. One of such differences is method dispatching. Groovy supports multiple dispatch, while Java does not. Therefore the following code works differently in Groovy and Java:

public class A {
public void foo(A a) { System.out.println("A/A"); }
public void foo(B b) { System.out.println("A/B"); }
}
public class B extends A {
public void foo(A a) { System.out.println("B/A"); }
public void foo(B b) { System.out.println("B/B"); }
}
public class Main {
public static void main(String[] args) {
A a = new A();
A b = new B();
a.foo(a);
b.foo(b);
}
}

$ java Main
A/A
B/A

$ groovy Main.groovy
A/A
B/B

Wednesday, June 01, 2011

Reversing Groovy switch statement

Recently I've been working on a Groovy code that had many methods with long multibranch conditionals like this:

def parse(message, options) {
if (options.contains('A')) {
parseARule message
} else if (options.contains(2)) {
parseSmallDigitRule message
...
} else if (options.contains(something)) {
parseSomeRule message
} else {
parseSomeOtherRule message
}
}

Although this code is working, it is hard to see which branch is called under which condition. It would be much better if we could replace this code with something like Lisp cond macro. The best candidate for such a task in Groovy would be a switch statement. If we could only refactor the code above to something like following, it would significantly improve readability:

def parse(message, options) {
switch (options) {
case 'A' : return parseARule(message)
case 2 : return parseSmallDigitRule(message)
...
case ... : return parseSomeRule(message)
default : return parseSomeOtherRule(message)
}
}

Unfortunately, this code doesn't work out of the box in Groovy, but it works if we do some metaprogramming.

The way switch statement works in Groovy is a bit different than in Java. Instead of equals() it uses isCase() method to match case-value and switch-value. The default implementation of isCase() method falls back to equals() method, but some classes, including Collection, override this behaviour. That's why in Groovy you can do things like this:

switch (value) {
case ['A','E','I','O','U'] : return 'vowel'
case 0..9 : return 'digit'
case Date : return 'date'
default : return 'something else'
}

For our purposes we need some sort of reverse switch, where collection is used as a switch-value, and String and Integer are used as a case-value. To do this we need to override default implementation of isCase() method on String and Integer classes. It's not possible in Java, but is very easy in Groovy. You can change method implementation globally by replacing it in corresponding meta class, or locally with the help of categories. Let's create a category that swaps object and subject of isCase() method:

class CaseCategory {
static boolean isCase(String string, Collection col) {
reverseCase(string, col)
}
static boolean isCase(Integer integer, Collection col) {
reverseCase(integer, col)
}
// Add more overloaded methods here if needed

private static boolean reverseCase(left, right) {
right.isCase(left)
}
}

Now we can use this category to achieve the goal we stated at the beginning of this post:

def parse(message, options) {
use (CaseCategory) {
switch (options) {
case 'A' : return parseARule(message)
case 2 : return parseSmallDigitRule(message)
...
case ... : return parseSomeRule(message)
default : return parseSomeOtherRule(message)
}
}
}

If you are comfortable with global method replacement, you can amend String and Integer meta classes. In this case you don't need to wrap switch statement with use keyword.

Anyways, with or without category, the final code looks better than the original noisy if-else chain. And you have learned the technique of reversing switch statement.