Five things I hate about Perl

Enough
advocacy, let's get to the nitty gritty of 5 things I hate about Perl.
(After brian d foy.)

  1. The difference between list and scalar context is subtle. One bug that bites people too
    often is this (for some value of "people", including me, far too often):

    sub myfunc { return }    my $scalar = myfunc(); # contains undef
    
        my %hash = (        key => 'value',        key => myfunc(),    );

    In scalar context, we get undef. But in list context, myfunc returns
    a list of zero elements. Guess which context hash declarations are in…

    Luckily in this case we'll get a "Odd number of elements in hash declaration" warning.
    Perl's warnings are mostly very useful and surprisingly helpful. However:

  2. Some warnings suck. Yes, some of them almost always point out an error (the void context
    error is useful: I usually find it means I've written: my $x => 1 instead of
    my $x = 1) but some are more irritating.

    When was the last time an 'uninitialized' warning had any effect on your code apart from making
    you have to sprinkle $x ||= '' throughout your code? Yet I usually restrain
    myself from adding no warnings 'uninitialized' because maybe one time in a hundred
    there's a genuine bug I need to know about.

    Similarly 'once' warnings sound useful, but in practise are usually because you've
    referred to a magic global that's used plenty of times in the library you want to use.
    For example, from List::Util's documentation,

    my $sum = reduce { $a + $b } @list;

    will warn about $main::a and $main::b being used only once. $a and $b are the canonical
    magical variables, wtf is that about? (mst suggests that these warnings are inhibited
    for sort only, which was their first use case).

  3. Argument passing. Yes, it's really flexible to be able to unpack
    @_ in any way you want but I'd like a proper way of doing it. (And yes,
    there are all kinds of solutions including Devel::Declare, but none are
    standard yet). Oh, and we don't have full destructuring bind, so yes, you can
    do ($x,$y) = ($y,$x) and my ($self, %args)=@_, but not my
    ({foo=>$foo}, [undef,undef,$bar]) = @_
    .

  4. It's a big language, with lots of syntax, several powerful minilanguages, a vast array of
    standard idioms, a large set of standard libs (including various incompatible ways of doing
    similar tasks) and a truly staggering number of 3rd party libs, CPAN, with even more ways of
    doing it. Actually, learning a big language is fine, but the bigness is one of the things
    making Perl difficult to parse. The other is the sheer amount of flexibility that Perl
    gives you to shoot yourself in the foot, change the way the language is parsed etc. Only
    Perl can parse Perl, and usually only after executing part of your code first. Yay for exploits
    on your language-aware text editor!

  5. Functional programming isn't easy or elegant. Yes, we have first class
    functions, but things like argument unpacking being ugly make it less
    convenient. Little kludges like the functions passed to map and grep taking
    $_ rather than the usual argument list @_ just add to the fun
    ($_ seems like a special-cased points-free hack, and it's far less
    consistent or common than Haskell's currying)

    I also dislike that regex substitution etc. can't be done as a non-destructive function.

Hmmm, there are probably more things, but those are the main ones. In particular
I don't hate references (yes, they take a little learning, and I'm aware that's a
stumbling block for most learners, but they are quite sensible once you do)
or OO (baroque, but quite capable, and see Moose for a cute modern take on
it).

Comments

  1. Dan Kuck says:

    If you don’t mind that it’s more than a year later…

    There is a way to do regex substitution and assignment on the same line and keep your original string intact.

    my $word = “Shitzu”;
    (my $substituted = $word) =~ s/zu//;

    It’s got a face only a mother could love, but it’s one line and by the end you’ve got a before variable and an after variable.

    I agree with everything else.

  2. S says:

    I’m sorry to say this, but you are utterly and completely missing the point of how to program elegantly if the “problems” you have with perl are actually problems for you.

    There are plenty of weird issues with perl, but seriously — you need to go and contemplate how to structure your code properly if you’re still doing $x ||= ” left and right… and being scared because a language is too _big_ is a problem with you, not that language.

  3. osfameron says:

    S. I didn’t say they were “problems”, just things that annoy me :-)

    You refer to my 2nd complaint: it’s true, that one comes up mostly when you’re refactoring legacy CGI scripts, for example just after adding ‘use warnings’. Sure, the warnings point out that I need to clean up the code but, um… I knew that already :D

    On the other issues:

    1) is something junior programmers get confused with all the time. It still bites me once every year or so ;-) I know context is something that we’re supposed to love in Perl, and I /often/ do, but now that I’ve seen things like Haskell’s type inferencing solve similar problems (but more powerfully and consistently) I sometimes find myself hating it.

    3) so annoyed Piers Cawley that he went off to program Ruby for a couple of years until rafl wrote MooseX::Declare…

    4) I suppose is arguably a good thing, but hey, I was being bad-tempered,

    and 5) I stand by: Perl could be designed better for FP (but see my Functional Pe(a)rls talk for some work on that ;-P)

  1. [...] Perl hate, and what to do about it: <tt>AUTOLOAD</tt>Hello worldAboutFive things I hate about PerlMore Countdown: laziness, Scheme, and German frogsSchwartzian transform in HaskellCountdown words [...]