Monkey See, Monkey Do

This was originally posted on another on of my blogs on 7 February, 2008.

I’m learning a new programming language these days, and got to thinking the other day about the lucidity of programming languages relative to English: given a simple program, how easy is it to read and understand? So I have devised a simple program which I have rendered in four languages: English, Groovy, Perl & Java.

English Monkey

Whenever a monkey sees an action, he does the same.

Short, sweet and to the point. This English monkey will be our baseline for evaluating the lucidity of other monkeys. Note the basic parts of this program:

  • the declaration (“…a monkey…”)
  • the iterative loop (“Whenever…”)
  • the set being iterated upon (“…sees an action…”)
  • the operation for each iteration (…does..)

Also note the use of pronoun (“he”) and reference (“same”). Clearly English is a language which has and relies upon a sophisticated sense of context.

Groovy Monkey

1def monkey = new Monkey()
2monkey.see().each { monkey.does(it) }

Nice. This Groovy program almost reads like English. In fact, let’s transliterate it to English:

Def monkey is new monkey.
Monkey see each, monkey does it.

That’s downright comprehensible! I like Groovy’s use of the pronoun it. That’s very English-ish. I’m not sure “Def monkey” really does make sense, but it sounds kinda urban and hip.

Perl Monkey

1my $monkey = new Monkey;
2for ($monkey->see) { $monkey->do($_); }

The Perl monkey program is similarly terse, and arguably even more lucid than the Groovy version (assuming you can get past all those crazy sigils!). Let’s transliterate into English:

My monkey is new monkey.
For monkey see, monkey do.

Whoa, that is catchy! That terribly punchy ending is made possible, in part, by the fact that Perl lets us reuse the “do” keyword, whereas Groovy does not (nor does Java). On the other hand, that pronoun “$_” really doesn’t have a comprehensible English counterpart. Happily the power of English expression leaves the whole thing perfectly lucid if we simply drop it.

Also, note the possessiveness in this program: it’s not just any monkey, it’s my monkey. Perl monkey implementers quickly learn to label everything that belongs to them so that other Perl monkeys don’t come in and just grab and use them as global variables.

Java Monkey

1import java.util.ListIterator;
2
3Monkey monkey = new Monkey();
4ListIterator see = monkey.see().listIterator();
5while (see.hasNext()) { monkey.does(see.next()); }

I’ll say this: Java monkeys leave nothing to chance. For this program I’ve chosen to bring in a useful tool. Some would say that the fact that Java monkeys use tools early and often is a mark of their intelligence. But in this case it just means that using a tool seemed a lot easier than writing the program with the stuff which comprises the Java language itself.

But how does it sound transliterated into English? Kinda like Vogon poetry:

Import java util list iterator.
Monkey monkey is new monkey.
List iterator see is monkey see list iterator.
While see has next, monkey does see next.

What kind of creature could listen to that and not be wracked with pain? It’s florid, murky, and verbose. Sometimes it’s downright misleading! And I could almost endure all of that if not for the occasional use of catchy alliteration which makes it seem like the author is actually saying something meaningful, stomped out in a tribal tattoo: ”monkey monkey is new monkey.

Far from using any sense of context, Java monkeys must eschew pronouns, and must often overstate matters, repeating themselves for emphasis: ”list iterator see is monkey see list iterator.” I like programming in Java, but when I see it in English, I have to admit it’s absolutely horrible.

How To Implement a Monkey

Obviously each of the above examples assumes that all participants in the context know what a monkey is and where to get one. Without that knowledge, none of them will work. So let’s not just fling.do() at all that messy complexity. Let’s see what it looks like to get an actual monkey in each of these languages.

English Monkey Guts

Don't make a monkey of yourself.  Instead, go to a
reliable supplier of monkeys such as a rainforest,
zoo or monkey farm, and pick out a nice monkey.
Preferably the monkey should be intelligent enough
to be trained, but not so intelligent that he
innovates.  He should have all the normal faculties
typical to monkeys in good working order (in
particular, eyes, hands, limbs, etc.).

Nobody’s going to argue that English has no expressive power. In fact it’s the baseline for expressiveness for this experiment. But as with many expressive languages, with great power comes great responsibility. While it may seem that the English monkey completely flubs the terseness test, bear in mind that it is far more difficult to get a monkey using English than it is in most computer languages. And as the program itself powerfully implies, making a monkey using English is practically impossible.

Groovy Monkey Guts

1class Monkey {
2    def see() {
3        ["scratch", "climb", "eat banana"]
4    }
5    def do = {
6        println "Monkey does ${it}"
7    }
8}

Once nice thing about (most) programming languages is the ability to create highly specialized monkeys, designed for specific functionality and which therefore omit many of the behaviors commonly associated with monkeys. An English monkey almost always has other methods, traits, and event handlers that aren’t pertinent to whatever it is you’re trying to get the monkey to do. It gets to the point that when you ask an English monkey to do something, you don’t know what’s going to happen.

But this monkey is a Groovy monkey, and only really does two things: he can see, and he does.

Perl Monkey Guts

 1package Monkey;
 2
 3sub new {
 4    bless {}, shift;
 5}
 6sub see {
 7    ("scratch", "climb", "eat banana");
 8}
 9sub do {
10    $self = shift;
11    print "Monkey does $@_[0]\n";
12}

The Perl monkey, like the Groovy one, is far more concise and focused than the English monkey. However, he isn’t quite as terse as the Groovy monkey. The Groovy monkey has an implicit sense of self identity; his identity comes from the Groovy language itself. The Perl monkey, on the other hand, finds it necessary to explicitly define himself (and as we discussed above, what belongs to him). Without a blessed reference to himself, he’s nothing more than a heap of monkey parts –any of which could be directly utilized by other monkeys, but you couldn’t really say that the monkey was doing things himself, because in Perl, without a “$self”, there really is no monkey to speak of.

So it would seem that Perl does not provide its monkeys with a sense of identity the way other programming languages do. Perl monkey implementers often regard this as a positive feature, however, since they tend to be fiercely independent and often identify themselves with more than one language in any case.

Java Monkey Guts

 1import java.util.ArrayList;
 2
 3public class Monkey {
 4    public ArrayList<string> see() {
 5        ArrayList<string> see =
 6            new ArrayList<string>();
 7        see.add("scratch");
 8        see.add("climb");
 9        see.add("eat banana");
10        return see;
11    }
12    public void does(String action) {
13        System.out.println(
14            "Monkey does " + action);
15    }
16}

Again we see that Java monkeys like everything spelled out in triplicate, and they often bring in extra tools sooner than the monkeys of other languages would need to do. But I think that the Java monkey’s psychological profile predisposes him to like this arrangement. He doesn’t really mind that his language is so far from English. After all, look at the English implementation of a monkey above: who really wants that kind of bloated, buggy monkey? You practically have to document usage guidelines and installation instructions right in the source code!

The irony here, of course is that Java is as vague when written in English as English ever was from Java’s perspective. I really do think that Java was invented by aliens with a signed permit to demolish the planet.

What does a monkey look like in your native tongue? I have a friend pondering what a Haskell monkey would look like. But I’d also really love to see your ideas for others; what would a functional monkey look like? Clojure Monkey? Arc Monkey? Erlangutan? Or how about a Basic Monkey? Is that even a meaningful concept?

In any case if you have an example of a monkey in any other idiom, please put it (or its URL) into a comment below; I’d love to include it and compare it to the above examples.