Then they came for your Java and Ruby

Recently, brian d foy posted a challenge to rewrite a Perl example in Stefik et al. (2011). In that paper, the authors infamously proclaimed:

Results showed that while Quorum users were afforded significantly greater accuracy compared to those using Perl and Randomo, Perl users were unable to write programs more accurately than those using a language designed by chance.

Quorum seems to be their pet language which they are pushing to replace actual programming languages in widespread use in the industry.

Stefik et al. (2011) describe the purpose of this ugly bit of Perl code:

$x = &z(1, 100, 3);

sub z{
    $a = $_[0];
    $b = $_[1];
    $c = $_[2];
    $d = 0.0;
    $e = 0.0;
    for ($i = $a; $i <= $b; $i++) {
        if ($i % $c == 0) {
            $d = $d + 1;
        }
        else {
            $e = $e + 1;
        }
    }
    if ($d > $e) {
        $d;
    }
    else {
        $e
    }
}

as

This code will count the number of values that are and are not divisible by c and lie between a and b. It then compares the number of values that are and are not divisible by c and makes the greater of them available to the user.

Of course, the code is weird. For example, instead of using for $i ($a .. $b), they use a C-style loop. In the C-style loop, they use post-increment, i.e. $i++ instead of using $i = $i + 1. But then in the if-condition, they don’t use post-increment. Also, who on earth initializes counters with floating point?.

OK, so their Perl is crappy. Not so shocking given their attitude towards it. In my blog post, I originally focused most of my criticism at their methods.

In response to brian d foy’s announcement of the challenge on Reddit, wschroed pointed me to another paper, this time by two of the original authors, Stefik and Siebert.

In An Empirical Investigation into Programming Language Syntax, they say:

… we found that languages using a more traditional C-style syntax (both Perl and Java) did not afford accuracy rates significantly higher than a language with randomly generated keywords, but that languages which deviate (Quorum, Python, and Ruby) did.

Talk about trolling!

Here are the Java and Ruby code snippets they provide for carrying out the task described above. See if you can spot anything odd.

public static void main(String[] args) {
    double x = z(1, 100, 3);
}

public static double z(int a, int b, int c) {
    double d = 0.0;
    double e = 0.0;
    for (int i = a; i < b - a; i++) {
        if (i % c == 0) {
            d = d + 1;
        }else{
            e = e + 1;
        }
    }
    if (d > e) {
        return d;
    }else{
        return e;
    }
}

def z(a, b, c)
    d = 0.0
    e = 0.0
    for i in a...b-a
        if i % c == 0
            d = d + 1
        else
            e = e + 1
        end
    end
    if d > e
        return d
    else
        return e
    end
end

x = z(1, 100, 3)

Again, counting with floating point! Who does that?!

Because the programs are not included as copy and pastable text in the main body of the article, I can only give you a screenshot, and hope that you can use those to verify the statements I make here.

[ Perl, Python, Java, Quorum, and Randomo snippets from Stefik & Siebert 2013]

But, more importantly, did you notice the problem?

In the Perl version, z(1, 12, 3) tests all integers from 1 to 12 inclusive to see if they are divisable by 3.

In both Java and Ruby versions of the code, z(1, 12, 3) only tests all integers from 1 to 10, inclusive.

So, while z(1, 12, 3) gives the right answer of 8 in Perl, in Java and Ruby, you get 7.0 (what’s up with counting with floating point?)

I guess because the person(s) translating the following code in Quorum:

integer i = a
repeat b - a times
    if i mod c = 0 then
        d = d + 1
    end
    else then
        e = e + 1
    end
    i = i + 1
end

got confused about the repeat b - a times.

The way I read this, it seems to me that the code would not test b with divisibility by c. For example, if you invoke z(99, 100, 3), that becomes repeat 1 times, and therefore, it seems to me it would only test 99, and not 100.

In the Java and Ruby cases, with z(99, 100, 3), the loop would not be run at all, as it would become for (int i = 99; i < 1; i++) and for i in 99...1, respectively.

Note that the Python code is funky as well. Python’s range(a, b) includes a, but excludes b.

I tried to run their entire Quorum code using their online Quorum compiler, but I kept getting errors. Maybe I made a transcription error of some sort.

[ Online Quorum compiler cannot run code snippet in Stefik & Siebert 2013 ]

What is interesting is what an inconsistent set of code snippets they managed to produce to implement just this one example case they give to their study participants.

And, their research agenda seems to be to undo decades of programming language evolution so as to replace the ones they don’t like with an intelligently designed language of their choice. Good luck!

PS: I oppose language zealotry. Programming is at its heart about manipulating abstract building blocks, and if you can actually program in one language, you can program in all languages … Unless you think typing speed has something to do with programming ability.

PPS: You can discuss this post on /r/programming.