Currently, I am conducting a natural language processing course. As part of the curriculum, I need to learn and code in Perl. I was exited! I was enthusiastic! However, the verb is "WAS". I am neither exited nor enthusiastic any more. I already have experience in C, CPP, C#, Java, Golang, Python, JavaScript, TypeScript and Bash. Among this versatile experience, Perl is now my second most hated language after Bash. Let me tell you why.
Weird variable access: I have worked with typed language where I need to tell the type. I have worked with weakly typed language where the language knows which is which. Then comes Perl. It is weakly typed. But, I need to prefix a variable by either
$
or@
or%
to tell Perl about the type of variable. And I need to do it every time I access the variable. Even more - the prefix changes time to time based on the usage.-
Too much implicit code: Remember, explicit is always better than implicit. But, Perl works the opposite way. Consider the following snippet.
while (<>) { print; }
What this does is reads from the input stream in
<>
this command, stores it in a variable named$_
, then prints that variable. Of course you can assign and use your own variable but Perl developers seem to prefer this. Well, I don't. Lacking readability: Continuing from the previous example, when someone sees that snippet, it is literally hard to get what it is doing. At least, it was hard for me.
-
No clear parameter list: While declaring a function (called subroutine in Perl), it does not specify the parameter list. You will always pass a list of arguments and the function need to extract them from an array. The end product is too much boiler-plating with too less readability.
This is what you will do, if you need to retrieve 3 parameters.
sub func1 { my $x = shift; my $y = shift; my $z = shift; // do something with the variables } func1(1, 2, 3);
-
Weirdly passing arrays to function: When you pass an array to a perl function, it flattens everything. Consider the following code.
sub func1 { print scalar(@_); } @a = (1, 2, 3); @b = (4, 5, 6); func1(@a, @b);
The
scalar
function returns the length of an array and the@_
variable holds the arguments as an array. So,scalar(@_)
will give us the number of arguments. What do you think the output is?2
? It should be. But, it's perl and the output is6
.
If you want to pass an array as an array, you need to make a reference of the array, pass the reference and de-reference it inside the function. Hell of a job for such a simple task! -
Weirder passing hash/map to function: Okay. When we pass something to a perl function, it flattens everything and makes a single array. What happens to hashes/maps? Well! It makes that an array too. And that array contains all the keys and values; in a single place. Consider the following code.
sub func1 { print join ', ', @_; } %f = (one => 1, two => 2); func %f;
What do you think the former code prints? My guess was it will print the keys of the map. At the worst case, it will print the values instead. Alas! The actual worst case worse than what I anticipated. It prints both keys and values. So, the output is
one, 1, two, 2
. And it becomes a mess when you want to reconstruct the map.
The mess gets messier if you call the function likefunc1 %f, three, 3
. How will you know what came from where? Cryptic RegEx handling: When you do a regular expression match, it automatically assigns some variables like
$&
,$`
,$'
etc. They are useful when you know them to be honest. But, when you just read the code, specially when you are from another background, it looks like a mess.Less Searchability: Consider the previous point. You are reading a perl program. You suddenly found use of undeclared variables like
$&
or$'
. So, you googled about it - "what does $' means in perl". Alas! while you search something on the search engines, they generally stripes out spaces and punctuation. You will still have relevant results. But, they won't be as great as if you search - "what does dir mean in python".Pathetic debugging support: The debugging support for perl is in a word pathetic. It only supports some basic commands and the error messages are cryptic. Once you are stuck in somewhere, you are DONE!
Too much implicit error handling: While the shown error messages are cryptic, there are a lot of errors that are not shown at all. Say, we have an array
@a
and we want to print it. Now, mistakenly we have typedprint $a
. It will just print nothing just like if the array was empty. In my opinion it either should through an error or print the memory address of@a
. It does nothing. And you will never know that you have an error there.-
Inconsistent behavior: Say, we have a function like this
sub one { return 'two'; }
Now we define two maps like the following
%m1 = (one => 1); %m2 = (1 => one); print %m1; print %m2;
It will print
one1
and1two
. Can you make any sense of it? Well, I could not for a while. Turns out if your map's value coincides with one of the functions, it will call that function and use the function's return value as the map's value. But, it will not do such if your map's key coincides with a function. Poor IDE support: So far I have not seen any perl IDE that satisfies me. You can add plugin to VS Code or JetBrains IDEs to support perl. But, they are buggy and are not feature-rich.
I just hate it: This is the full and final reason. And, I guess, this is sufficient reason to hate a language that I just hate it.
John Lennon dreamed of a world without religion. I dream of a world without perl.
Top comments (15)
I should point out that you've been mentioned in today's issue of the Perl Weekly newsletter, so you'll probably get a few more comments over the next few days. I hope the Perl community will keep things civil, but I can't guarantee that.
I've been teaching Perl for twenty years and you raise many of the same problems as a lot of beginners in Perl. In many of these cases, things are how they are because the increased power and expressiveness they bring to the language. Let me see if I can explain.
Sigils are an important part of the language. I confess that I now get slightly confused when I use a language without sigils. But one big thing they bring is the ability to directly interpolate variables into strings -
print "I have $x problems, but Perl ain't one"
. This is such a common requirement that I think it's a net gain for Perl.The number of bugs in your code is proportional to the amount of code you write. Writing less code means introducing fewer bugs :-) Of course, you can add the missing variables yourself, if you want. No-one is going to stop you.
Honestly, I think readbility just comes down to practice. Oh, and (self-imposed?) coding standards. There used to be a thing where Perl programmers tried to write code that was as short as possible or as hard-to-read as possible (just for fun, you understand, that code wasn't mean to be used in real projects) and I think that gave Perl a misguided reputation for being hard to read. It doesn't need to be like that.
Perl now has support for subroutine signatures. They're currently marked as experimental, but I expect that will change pretty soon. They're really powerful.
Perl's parameter passing consistently confuses people from other languages. Honestly, I think that flattening aggregate data structures into
@_
was one of the biggest mis-steps in Perl's design. I'd love to see@arrays
and%hashes
passed into subroutines as single elements of@_
. But Perl loves backward compatibility and that would be almost impossible to achieve now. The best alternative I can suggest is to only use anonymous arrays ($array = [ ... ]
) and hashes ($hash = { ... }
) instead. Actually, thinking about it... that also removes the need for many uses of the@
and%
sigils, so it might solve a lot of your problems from point 1 as well.Most of this is covered in point 5. But, yes, when you unroll a hash into a list, you get a list of key/value pairs. And they're in random order. But you populate a hash by giving it a list of key/value pairs -
%french = ('one', 'un', 'two', 'deux', ...)
- so I don't think that's too surprising.It's mostly possible to use regexes without needing to use variables like
$'
and$&
. You can even get away without the capture variables like$1
and$2
. And the/x
option on the match operator makes it possible to write regexes that contain whitespace and comments. As I said in point 3 - Perl doesn't need to be written to be as unreadable as possible.This is true. But the search function on the Perldoc web site doesn't ignore punctuation.
Perl's built-in command line debugger is pretty grim. Most Perl programmers ignore it (fun fact - we'd improve it but I don't think anyone understands the code!) Many IDEs have hooks that understand the Perl debugger and present it to you in a much nicer manner.
Here's a good tip. Always add
use strict;
anduse warnings;
to every Perl program that you write. They will catch many of this silly little slip-ups that we all made. In your example, you would have seen the warningUse of uninitialized value $a in print
.Two things going on here. The left-hand side of a "fat comma" (
=>
) is always interpreted as a string. And the right-hand side is an expression. Expressions can contain function calls. So your real disagreement with Perl here is that you don't want Perl to execute subroutines if you don't explicitly put parentheses after the name (one()
). Perl programmers like to omit unnecessary punctuation, but I can see your point here. I think it would be great to have an option that allows a programmer to demand parentheses on subroutine calls (something likeuse sub_parens
). I should also add that if you want Perl to see a string as a string then the best approach (as with most other languages) is to put it in quotation marks.There's a saying that "only
perl
can parse Perl". It means that Perl syntax is so complex that only the compiler (the programperl
) can completely parse the language (Perl). There are projects going to produce easier ways to parse Perl (PPI is a well-known one). But, yes, IDE support for Perl needs to improve.Honestly, hate seems like a strong emotion to use on a programming language. But that's your right, of course. Honestly, the way the industry seems to be going now I think it's very unlikely that you'll need to use it once this course is over.
10 - That's only a warning, the program would still run. Sadly
$a
is a global variable. I think a better advice would be to actually use more meaningful variable names (in addition to strict / warnings of course), and especially avoida
andb
at all costsYeah, I described it as a warning. His original complaint was that the program continued silently - so a warning is an improvement there.
You're right, of course, that better variable names is always a good idea. But no matter how descriptive the name is, you can still mistype the sigil.
Iβm sorry you had such a poor initial experience. Maybe I can help you through some of the rough spots, considering this seems to be a requirement for your course? Iβve been developing in Perl professionally for the past twenty-five years and can assure you that there is logic and reason to it.
Email me at mjg@phoenixtrap.com and we can work things out.
Regarding point 4, why are you using that syntax? With recent (at least 10 years old I think) versions of Perl you can just do:
If for some reason you need to use a very old Perl interpreter, there's still a better solution:
Michele.
It was Perl 5.20 that introduced subroutine signatures (in 2014). And they're not widely used, I think, because they're still marked as experimental.
One thing I agree with, is that they likely should be not be marked "experimental" anymore. ;-)
Getting things from experimental to in and from deprecated to out are not tasks that happen in Perl.
I think the reason that modern IDEs does not have good support for Perl, is that there are too few people working on implementing that support. If you want to improve IDE support in Perl I would recommend contributing (submitting PRs), see for example: github.com/richterger/Perl-Languag.... If you are a beginner in Perl, asking questions at stackoverflow.com and perlmonks.org are also great ways to get involved in the community and learn more.
I've read criticisms of perl in the past and some of them are valid, but, the above seem to come from a poor grasp not only of perl, but of languages in general. Sorry, but the average programmer who reads e.g. Learn perl in 2 hours 30 minutes, should be clear on almost all the points most of which stem from a misunderstanding of what perl arrays & hashes are and a misunderstanding of what values vs references are in general.
There's also a misunderstanding of how language parsers work too, I'll take example 11 for that. Perl does give you the convenience that for keys of perl hashes you don't have to quote the string (as long as it starts with a letter). But, why do you think an unquoted value would be interpreted as a string, how would the parser know it is a string? Would the string
one
as a value work in ANY other language unquoted? A bare word like that in most languages would either be a function call or macro or a syntax error, how could it ever be a string? Why would anyone be confused by that? If you don't like "inconsistency" you can avoid perl's handy skipping quotes for key strings and do it like on any other language:Since you don't understand even such basics, I can't go into how the usage of $/@/% (based on older shell languages, so it was mostly familiar to shell programmers) apart from having a learning curve helps the parser in order to make a more powerful syntax for the language.
Sorry to be like that, but it is rarely that I see such ignorance from someone who claims to have programming experience in multiple languages. I've used over a dozen languages over the years and always choose the right one for the job - even though I have personal favourites (yes, for a quick shell script you cannot beat the expressiveness of perl).
And, importantly, as long as you're using the fat comma to create the key/value pair.
At point 5, I don't see any overhead in using references. It's just the same amount of code...
Same applies to point 6:
Hope this helps!
Michele.
"Weird", in my book, is something that doesn't match pre-existing models in someone's head, i e tells more of the person's close-mindedness than anything else. In other words, haters gonna hate.
No programming language can read your mind (point 6, among others). If you want the keys, ask for them:
If you want the values, ask for them:
Perl absolutely has its uses in low-level shell scripts, running server-level heavy-duty functions.
The problem that I see with Perl is its connotation as an older, early-born language that hasn't evolved (even though Perl totally has) -- very likely correlated (if not caused) by your 12th point.
As for point 13, this is my go-to example of Perl:dev-to-uploads.s3.amazonaws.com/up...