So Why Isn’t Perl My Favorite Programming Language?

A good long while ago, I tried doing an exercise that I was considering making into a standard job interview question: “For each of your ‘languages of choice’, tell me 5 things you like about the language, and 5 things you dislike about it.” My languages of choice at the time were Perl, PHP, and JavaScript, and my answers quickly showed me why this was not the best interview question:

It was far too easy to come up with dislikes, and not so easy to come up with likes. It was a perfect example of the adage that “Every programming language sucks, but some of them suck more.”

That said, the one language that scored more likes than dislikes, for me, was Perl. Here are some of the things I like about Perl:

  1. Different sigils improve readability. The only data types that matter in Perl are easily distinguished. While we’re at it, ensigillizing your variables means you can stick them in print statements without having to step out of the quotes: print "foo equals $foo and bar equals $bar" is pretty easy. A sigil-less language like JavaScript requires print "foo equals " + foo + " and bar equals " + bar so the interpreter knows when to print the value of foo and when to just print the string “foo”.
  2. Scalar vs. list context means the language effectively doubles its potential function namespace, because each function can (potentially) return one thing in scalar context and another thing in list context. (For example, the “grep” function can either return a list of matches, or just the number of matches it found.)
  3. The language is compact. (Contrast this with PHP…)
  4. Function names are generally chosen pretty well, so that an experienced programmer can generally get a good idea of what the function does. (Contrast this with, for example, Prototype.js’ Enumerable.include() method. This name looks — at least to me — like it should do something, but instead, it actually returns a Boolean based on whether the Array, Hash, or Object in question contains the given property. I understand this is based on Ruby’s Array.include? method, but the removal of the question mark results in a confusing name.)
  5. Nearly all built-in functions have default arguments, which are sensibly chosen. For example, if no array is passed to shift(), it will shift @ARGV. By default, print() prints $_, and pattern matches match on $_.
  6. The presence and uses of the $_ variable are reminiscent of pronouns in human languages. Once I’ve referred to, for example, “John”, I don’t have to keep calling John “John” every time I want to talk about John. I can just say “him”. Similarly, once I’ve set up, for example, a while (<FILEHANDLE>) construct, I don’t have to refer to each line as $line. I can go ahead and pattern match on $_ without having to construct an extra variable. And since the pattern-match operator operates on $_ by default, I don’t even need to mention it… This is huge. This is a core part of what makes Perl Perl. Effectively, it has pronouns.
  7. The language doesn’t enforce any particular programming paradigm. It easily supports procedural, object-oriented, and functional programming. It has anonymous functions, first-class functions, and closures.
  8. Regex extensions like \b, \d, and \s, and especially \W, \D, and \S, make my life easier. (I continually miss them when working with non-Perl regexes, such as egrep.)
  9. The standard substring-finding mechanism (“do a regex match”) returns Boolean. This stands in stark contrast to the more usual substr(), which tries to do too much: it returns the position at which the substring was found, or an out-of-band value (such as -1 or Boolean false) if the substring wasn’t found. This means that if I just want to know if the substring was in there or not (but I don’t care where it was), I have to do an extra check against that out-of-band value. For example, I have to do if (false !== substr($haystack, $needle)) in PHP, or the equivalent if (haystack.match(/needle/) != -1) in JavaScript. Note that JavaScript, even though it uses a regex match, still returns a positional integer instead of a strict Boolean! This gives me too much information, making me hang an ugly-looking “!= -1” off the end for no benefit.

By the way, just to round out the list, here are a few of the things I dislike about Perl:

  1. You have to manually unpack and assign function arguments? What was Larry Wall thinking?!? I’m okay with “sub” instead of “function” as the function declaration keyword (just barely), but not being able to declare the argument names as part of the function definition? That’s just bizarre and weird, and it hurts every time I have to write a separate my ($foo, $bar, $baz) = @_; line after the sub foobar { part.
  2. And in every single class method, you need to manually unpack a reference to $self! This is, I’m quite sure, intimately related to the previous problem. But it’s another context in which I keep encountering the problem. Stupid boilerplate like the existence of my $self = shift; in every single method everywhere should simply not ever exist; it should be abstracted out and taken care of automatically.

At one point, I had high hopes that Perl 6 would fix these problems. At this point? The momentum has been lost; the interest in Perl has shifted to other languages (largely Ruby and Python). I recognize that Larry Wall and the Perl team are proceeding at their own pace, and that they’re more concerned with doing it right than with doing it quickly. And I appreciate that.

But they’ve taken so long that I doubt anyone really cares much any more. Perhaps Perl 6 will manage to reawaken interest in Perl… but if so, it’ll be starting from scratch, rather than building on Perl 5’s preexisting popularity. Which is kind of a shame, because there’s so much to like about Perl.

One Trackback

  1. By Kagan MacTane on Wednesday, August 26th, 2009 at 10:50 am

    On Twitter, Kagan MacTane said: New blog post: So Why Isn’t Perl My Favorite Programming Language? http://bit.ly/CWje2
    Trackback powered by Topsy

Post a Comment

Your email is never shared. Required fields are marked *

*
*