Monday, August 24, 2009

Archaic Perl

A couple of days ago I had to attend a vendor who came to offer their services for the development of a web application.
As one of the participants of the organization had to handle some unexpected event, I took the opportunity to start a small research during casual conversation: "What development tools do you use at company?". In an ideal world the answer would have been: "Perl", but they told me that they work mainly in Python, but can work in other environments, including Perl. After informing them that the organization prefer Perl for the development of our applications, and after a micro religious debate, one of them (Juan) concluded:
In the end anything that can be done in one language that can be done in the other, but Perl programming is just more archaic.
that nearly upset me, but given that the missing guy arrived and the important issue was the meeting, I remained calm.
Now in retrospect I wonder: what he meant by saying that Perl is archaic? Perhaps John was referring to Perl 1 (1987), which was a kind of Shell Script with grep, sed and awk included, he could even think  that until Perl 4 (1991, soon after Python 1.0), however the current age is Perl 5 (1994) and viewing the subject young age, I think that Juan couldn't find a word to describe the mythical defects of Perl, so he ended up using the wrong word.
If Perl is archaic, then probably the object-oriented and functional programming are too, however those are the two technologies with most momentum at the present, and given that Perl's own object system was copied from Python, I will assume he meant some of the following:
  1. Perl is ugly
  2. Perl is messy
  3. Perl is unreadable
  4. Perl is incomprehensible
I will briefly address these prejudices that have been widely circulated on the Internet and for which there is no real support, much less after the rebirth of Perl (which I will discuss in another article).

Perl is ugly

As this is a matter of taste, things which are ugly to some one may be very attractive to other. But assuming that Perl is one of the ugliest languages, it has features that make it a practial language to solve a lot of problems easily.
One of the features that make Perl syntax leaning (not necessarily ugly) are the sigils indicating the type of each variable, however this feature facilitates extensibility and allows the interpolation in strings, and when I say Perl is extensible I mean that we can intervene in the compilation process to change its original syntax, a very high level feature shared with few languages, and the basis of the domain specific languages (also called DSL) that are very useful and popular. Perl offers at least three different mechanisms to achieve this goal.
Another feature is the practical integration of regular expressions within the language, therefore making extensive use of them, unfortunately, these expressions are ugly no matter what language are you using.
Take for example the parsing of a specific instruction from LaTeX:

\begin{document}

In Perl it would look something like:

if ( $latex =~ m/\\begin\{[az]+\}/ ) ...

In Python it would look like:

pattent = re.compile(r'\\begin\{[az]+\}')
if pattern.match(latex):
...

In fact neither is nice, but  Perl is really more succinct and easier to understand, and I will not show the hassle to use them from Java.
Finally there is the holy argument about coding style and all that nonsense about the compiler enforcing to write the code in a good style. I say this because even when I think you get used to "the right coding style", it is also true that sometimes this is a nuisance and gets in your way, and in such cases there is no remedy. Below there is an example of Python code hard to format because of inflexible language syntax.
When code requires a particular style, you should use formatting tools, for example I use indent for C, and perltidy for Perl, lately I write my Perl code in the following style:

perltidy -l=99 -sbl

No matter how I get code delivered or if I type it myself, because I can convert it into my standard style with a single command, even before saving it (I use vim).

Perl is messy

Languages are not messy, people are.
However, there are languages that have more features than others to organize a project, Perl provides several ways to organize the code to suit many needs, ranging from programming on a single line (command) to the construction of large and complex applications.
The language allows the creation of procedural modules with their own namespaces, which may even be organized into multiple files to be loaded "on demand", very enterprise, isn't it?.
While most languages only have a fixed way of handling objects, Perl has a basic object system that allows to implement OOP in many ways, like the language motto says: "there is more than one way to do it".
Perl avoids to force the programmer to follow a particular structure, whether it fits the needs of a specific program or not, otherwise it would be like Java.

Perl is unreadable

This is just a particular combination of the two myths that preceded it, but it is also argued that you can not read the code wrote after 15 min., and that may be good some times, because it allows you to write programs quickly even if they are dirty, after all nobody wants to design and document code following the principles of software engineering to understand the last program I wrote a few hours ago, only because I needed a hint on the character frequencies in a dozen files:

perl -MYAML -ne '$c{$_}++for split//;END{print Dump\%c}' data.txt

It is easier to write this again than trying to understand it, of course this is easy to make in Perl because it has some magical constructs, do not try something like this in another language, because your best scenario is to make it work, but I guarantee that it will be much longer and difficult.
But Perl also allows you to write nicer code if it were necessary:

use YAML;
use IO::File;
use strict;

my %counts;
my $fd = new IO::File $ARGV[0], "r";
while ( my $line = readline($fd) ) {
    for my $letter ( split( //, $line ) ) {
        $counts{$letter}++;
    }
}
print YAML::Dump( \%counts )
I'm sure this is as easy to understand as Python or Ruby for a programmer, isn't it?. Then the issue is not if the Perl language is unreadable, but the motivation to write the program, and the programmers expertice to write code easily readable or maintainable even by less experienced colleagues.
Finally, the least of my worries while making the last example was formating the code, since my editor did most of that work automatically, but just in case, I used perltidy on it, for you to see how well it looks.

Perl is incomprehensible

For whom?, Japanese is incomprehensible to me, but I doubt that to be the case for most people living in Tokyo, Perl is equally incomprehensible to someone who is not trained to understand it. In the previous section I showed you that Perl code may be as clear as Java or Python counterparts.
Certainly there is a lot of Perl code that is virtually incomprehensible except for the language gurus, but that doesn't mean that the programs should be written that way.
The shorthand form that allows to obfuscate Perl code also makes perl not just an interpreter, but a very useful tool in the command line, also allowing the expression of the genious and expertise over the language. There are very few languages that allow yo do JAPHs as Perl.
The fallacy appears when people start saying things like: "Perl is evil because it allows those things", or my favorite: "It is impossible to write unreadable programs in Python", really?, lets see who understands this little program written in Python:

for n in range(12):
    exec("abcdefghijkl"[n]+"=lambda x=0,y=0: "+filter(
        lambda x:x not in "\n$\r","""(x*y#x/x!range(x,
y#x+y!b(1,1#d(e~,e~#d(f~,f~#c(e~,e~+d(g~,d(g~,g~))#"%4
d" % a(x,y#map(lambda y:i(x,y),h~#" ".join(j(x)#"\\n".
join(map(k,h~))""".replace("~","()").replace("#",")!")
        ).split("!")[n])
print l()
and I can find much nastier things written in Java, which means you can write bad and incomprehensible programs in any language, and probably rookies can do it only because they are naive.
However, full potential of the developers may not be unleashed unless the language provide the highest level abstraction mechanisms, and in this case languages like Java and PHP are pretty bad while Perl outperforms Python and Ruby easily, disqualifying any possibility to label Perl as archaic.
Perl can be as corporate as any other language, and mastering this language in an organization is an investment where the code can be used and reused in many ways: from systems administrators to developers, via the database managers etc., and in solutions ranging from simple command line operation to the development a corporate application.