Stop with the Perl golf already!

It’s annoying to read critics complaining that  “Perl looks like line noise” since that’s definitely not my experience… at least, most of the time.

There are some places where I think Perl actually does look a bit “noisy”:

  • sigils ($@%&), but only when most variables have single-letter names ($i,$j,$k, etc.)
  • punctuation-only special variables ($/, $], etc.), but I find these are used infrequently in most “real” code I write or see
  • explicit dereferencing (@{$foo->{bar}})
  • regular expressions, but this is hardly Perl’s fault

But when I think about where the reputation for line noise comes from, the thing that jumps out at me is the Perl (sub)culture that turned code golf and obfuscation into a source of pride – a demonstration of high art and coding wizardry.

Think about it.  IBM has a technical paper on JAPH’s and describes them as “a mainstay of the Perl culture”.  Obfuscated perl shows up on tee-shirts.  Perl Monks has an entire section on Obfuscated Perl.   The sigils themselves even became the logo on the official shirt for YAPC::NA 2008 as a visual pun on the Chicago city flag.

So, of course, people are going to equate Perl with line noise.

And who am I to be throwing stones?  I’ve done it too.

I recently gave an answer on StackOverflow to the question, “What’s the shortest perl program you can write for the number guessing game?” That question and the subsequent answers were  the genesis of this article.

I had the idea to show how the guessing game could be played recursively to golf by avoiding variables to hold guesses.  Just for the sake of argument, if I were writing it out for someone to understand it, here’s how I might do it:

use strict;
use warnings;
my $target = 1 + int( rand(10) );
my @message = ('', "too much\n", "too few\n");

sub guess {
  print "Gimme your guess 1-10:\n";
  my $guess = <STDIN>;
  my $comparision = $guess <=> $target;
  if ( $comparison ) {
    print $message[$comparison];
    return guess();
  }
  else {
    return $target;
  }
}

my $answer = guess();
print "Bingo! It was $answer\n";

And here’s the short version I came up with:

($t,@m)=(1+int rand 10,'',"too much\n","too few\n");sub g{print
"Gimme your guess 1-10:\n";syswrite(STDOUT,$m[<><=>$t])?g():$t;}
print"Bingo! It was @{[g()]}\n"

That’s not even that bad as obfuscation goes, but I looked to the two really nasty bits ( “<><=>$t” and “@{[g()]}“) and though to myself, “Damn!  No wonder people complain about line noise!

It reminds me of a quote about discrmination by the US chief justice.  Adapted to this context, it means the way to stop people thinking that Perl looks like line noise is to stop Perl from looking like line noise.

That’s my new pledge.  No more Perl golf and no more JAPHs for me.  The Perl I’ll take pride in is Perl that people can read.