Common Criticisms - Page 161
March 19, 2001
One of the most common criticisms of Perl is that it's difficult
to read other people's code. Individual differences in coding
style can be significant. The adoption of conventions in Perl,
when encouraged, tends to favor compact code versus legible, less
tightly packed forms. Aside from structural flexibility, there
are often many ways to accomplish the same task. Indeed, this is
another point of pride among many, as heard in the Perl motto
"there's more than one way to do it" (in fact, that motto is
printed right on the cover of Programming Perl, 3rd
edition).
A classic Perl strength — the ability to knock out code
quickly because you can use the first approach that comes to you
— suddenly becomes a weakness when someone else needs to
work with your code, and has to practically burrow inside your
head to figure out what you were thinking at the time. You may
even have to ask yourself what you were thinking if you ever
revisit a Perl script that you'd written several months prior.
The typical defense of Perl's lax coding style is rather
libertarian in nature, espousing a sort of self-regulation:
Programmers should use discipline, the argument goes, if the
project calls for it, rather than asking the State (e.g. the Perl
language) to impose rules of order. But the varied backgrounds of
Perl programmers make it all but impossible, in reality, for
meaningful conventions to add structure to an unstructured
system; and, besides, while restraint by the State may be a great
philosophy for a civil society, Perl is a pragmatic programming
tool, not the Declaration of Independence.
Spaghetti Symbols
Another factor that contributes to the illegibility of Perl code
is the language's heavy reliance on iconic symbols. Single
character symbols can carry a lot of meaning in Perl, such as the
$ that represents a scalar, the @ that
represents an array, and the different styles of brackets and
braces. For some it becomes a burden to associate a large number
of concepts to abstract symbols, making it mentally taxing to
read and comprehend a line of code such as:
@{$thehash1{$thehash2{$$keylist[$keyidx]} } }
Basic legibility of a programming language should not be a hazing
ritual. The meaning of symbols becomes even more obfuscated when
you start talking about references in Perl, which are basically
cloaked in misleading symbols. It's one thing to remember that a
$ precedes a scalar value, but when that scalar
value is a reference to a hash, but the hash symbol
% is nowhere to be found, you have to start digging
through the code to pull apart just what sorts of values you're
dealing with. Again, especially difficult for teams of
individuals working with code they themselves did not author.
Perl is also big on inference and implication. Consider the
matter of contexts, where an expression may yield a different
result whether it is interpreted in a list or a scalar context.
While context is inferred from syntax, it takes an extra level of
mental thought to consider, based on syntax, the interpretive
context of an expression. Those who favor clear programming tools
take issue with the principle that interpreter behavior can so
often be based on implicit directives rather than explicit ones.
On a similar note, Perl loves implicit variables. While the
disciplined programmer may make every variable clear and obvious,
many use Perl shortcuts to rely on built-in implicit variables
or, even worse, implicit variables by omission. Consider three
variations of a foreach loop.
First, with an explicit variable:
foreach my $counter (1..10) {
print $counter;
}
Above, a newcomer to the script quickly spots that
$counter is the variable assigned to the loop and
being output. Consider this same code using Perl's implicit
variable:
foreach (1..10) {
print $_;
}
No variable is explicitly assigned to the loop, so Perl assigns
the variable to the implicit $_ variable. While it
doesn't take a genius to understand this code, it's one shade
removed from perfectly clear. How about we remove all variable
references entirely?
foreach (1..10) {
print
}
Now we see Perl at its implicit finest. Since no variable is
assigned to the loop, Perl assigns it to $_.
Similarly, as no arguments are presented to the
print statement, Perl assumes $_. The
output is exactly the same as the first example, but to a reader,
very little is happening at the visible surface. Critics pounce
here, and say that this third example is exactly what gets us
into trouble with Perl. Defenders point back to the libertarian
argument for self-discipline: "don't do that". But the fact is,
programmers do do that, regularly. Because they can.
The Perl You Need to Know Part 22: Warts and All - Page 160
The Perl You Need to Know Part 22: Warts and All - Page 160
Simplistic Subroutines - Page 162
|