Hacker News new | ask | show | jobs
by kluck 3146 days ago
I begin to find the constant bashing of Perl amusing. Such a great language, people just use it and it gets stuff done. I have no explanation as to why people hate it, other than because most people just don't understand Perl.
1 comments

I've used Perl since 1991. I've spent more than 80% of my career writing and maintaining Perl. I get paid large amounts of money to come in and help people sort out their Perl projects.

... it's not a great language; it's a clusterfuck of "cleverness" which lets "clever" people implement horrifying glass cathedrals that shatter as soon as you open the door.

(And there is some selection bias here, I'll admit - the people who control their Perl programmers and enforce simple, readable code don't need contractors to rescue things. It's generally only the hideous fractals of fuckery I get to see.)

> ... it's not a great language;

Yes it is.

> it's a clusterfuck of "cleverness" which lets "clever" people implement horrifying glass cathedrals that shatter as soon as you open the door.

It is clever, so are most other languages. It lets do people do horrible stuff, as well as wonderful stuff, same as in most other languages.

The Perl code from other programmers that I usually come across is mostly using established popular CPAN modules and/or frameworks that encapsulate the "clever" parts. I think you are right in that you mostly get to see Perl code that does need help, rather than the better maintained Perl code that does exist as well.

I agree it is a great language, but you need to have discipline and a coding standard to avoid the pitfalls of TIMTOWTDI
Agreed -- there are far too many pitfalls that you only really learn through debugging strange behaviour. Autovivication is a perfect example of this:

  perl -wE 'my @test; say $test[5]{yes}[0]{ok}++; say scalar @test; say ref $test[5]; say $test[5]{yes}[0]{ok}'
outputs:

   0
   6
   HASH
   1
with not a single warning
Why would there be a warning? Your example does exactly what autovivification is supposed to do. Obviously you don't normally use it as obscurely as you've done here.

I hate C#'s way of assigning a value to a dictionary, without autovivification:

    if (dict.ContainsKey("yes"))
    {
        dict["yes"] = val;
    }
    else
    {
        dict.Add("yes", val);
    }
You also have to use ContainsKey before you try to use [] to retrieve a value, because [] throws an exception if the key doesn't exist in the dictionary. Perl's autovivification, which assumes you know what you're doing and expect the key to be there when you ask for the value rather than explicity check for the key, makes much more sense and is a lot easier to work with.
>which assumes you know what you're doing

This is exactly my point, there should be no autovivification - I'd wager most people using perl these days don't know what they're doing, they're reluctantly editing some legacy code.

It's a dangerous default behaviour that can lead to very hard to debug errors. Most languages don't do this so people don't expect it; I don't know C# but can immediately tell what the code you wrote is doing. Explicit is better.

It's extra confusing because if you try and dereference undef without accessing a value it's an error:

  perl -Mstrict -WE 'my $test; say @{ $test };'
  Can't use an undefined value as an ARRAY reference at -e line 1.
What harm is there in a warning? You can disable classes of warnings in perl if you want to, or turn them off completely. I would much rather be explicit so I don't accidentally use some magic.
Explicit isn't better when the explicit boilerplate overwhelms and hides the intent of your code.

For the C# example, this can cause an exception:

   dict["yes"] = "val";
If the dictionary already contains an entry with the key "yes", the line will assign "val" to that entry. But if there is no entry with that key, an exception is thrown. The alternative is to use the Add() method, but that throws an exception if the key does exist, and works if it doesn't. I can't imagine any common use case of dictionaries where this behavior makes sense.

So what you're left with is a bunch of boilerplace and an if/else branch wrapped around every place you want to set a value in a dictionary. It makes dictionary use very cumbersome, which obscures the intention of code that uses dictionaries and, worse, discourages their use. C#'s design here takes away a very handy data structure that can make entire classes of problems easy to solve.

Perl's dictionaries, aka hash types, are used everywhere in Perl code. They're extremely useful and flexible, and a lot of that is due to the ease of use that autovivification brings.

I don't think it's fair to judge a language (or any tool) by how difficult it is to use by someone who rarely uses it and has no desire to learn, rather than by how usable it is for someone who uses it all of the time.

> than by how usable it is for someone who uses it all of the time.

Most of my career since 1996 has been in developing Perl. I'm a contractor who gets hired (and paid well) to help with Perl projects. By no stretch can you say I "rarely use it".

And I still consider Perl one of the more difficult languages to deal with because it's very easy to rely on implicit behaviour that - whilst perfectly clear as you develop it - makes life inordinately hard a year later when you're trying to debug an edge case because now, e.g., people can have two different delivery methods in the same basket (whoops, the second one overwrote the first one in the hash!)

> Perl's autovivification, which assumes you know what you're doing

Which is fine if you're the only person who will look at this code and we're talking about a timespan of a few hours.

When someone comes to deal with this code a year later, it makes life more difficult than it needs to be; at least the C# way is explicit - you can come back to that years later and know exactly what's happening.

(Which is the basic problem with most of Perl's magic - coming back to it hours/months/years later makes life harder for no actual gain.)