Perl vs. Python


I’m not one to generally get involved in technical “religious” wars —
vi vs. emacs, perl vs. python, Windows vs. Mac, etc. Each one has its advantages
and disadvantages, and I have my preferences, but
arguing about them is rarely productive. Having said that, there were a few
comments on my previous (and completely unrelated) entry
that raised the perl vs. python argument. I don’t think perl is inherently
unreadable, and it’s certainly possible to write easy-to-read, coherent perl
code, but in general, I tend to agree with Tom.

I am a professional software developer, and have been since my first co-op
work term in 1988. (Aside: so is MC, and he’s been doing this longer than I have.)
I have written code in many different languages, including C, C++, Objective-C,
perl, python, Java, REXX, Basic,
PHP, Tcl, Lua, plus a few at university that I barely remember: Fortran, COBOL,
Ada, Lisp, Prolog. Of these, the ones I use regularly in my job are C, C++, perl,
and python. I know C and C++ inside out and backwards, but when I am writing any
significant code in perl (i.e. more than a handful of lines), I almost always have
the perl online documentation open in another window — that’s not always
true for python, and I’ve been writing perl code years longer than I’ve
been writing python. I don’t think that the perl code that I write is more
complex than the python code, but the python syntax just seems more intuitive.

Say I have a list of filenames to process. In python:

files = [ 'file1', 'file2', 'file3', 'file4' ]
for i in files:
    # do something with i

Fairly straightforward. In perl:

my @files = qw( file1 file2 file3 file4 );
my $i;
for $i ( @files ) {
    # do something with $i
}

A little weird (what the heck does “qw” mean?), but not too bad. You
could also use

my @files = ( 'file1', 'file2', 'file3', 'file4' );

which is a little more intuitive, though I had to check the perl docs to see
whether to use parens or curly brackets.

A note before
I go any further — in perl, there are a zillion ways of doing
anything, so the code examples I’m listing here may not be the simplest
way to do things. This, in itself, is part of my problem with perl — after
ten years of writing perl, I should know how to do a lot of these relatively
basic things, but without checking the documentation or an existing perl script,
I frequently find that I don’t. I’ve only been writing python for about 5 years,
and I seem to remember its syntax and the majority of the language weirdnesses a
lot more easily than perl.

OK, now, what if you want to add something to the list later? Python:

files.append( 'file5' )

Obviously, if you want to add to the end of a list, you “append” to it. Very
intuitive. In perl? Well, I’m not sure. I’m currently looking through the perl
documentation, and it’s not obvious how to add an element to a list. I’m sure
there’s a way — maybe $foo += 'file5'; or
$foo .= 'file5';. Maybe it’s a documentation issue and not a language
issue, but whatever way it is, it ain’t obvious.

Another thing that confuses me about perl is there are a number of different
“types” (scalars, arrays, and hashes), and you can seemingly convert one to the
other whenever you want, and sometimes when you don’t want. First of all, is a
“list” the same as an array, or is it a special type of scalar? I don’t know.
Here’s how to set up an array in perl:

@foo = ( 'a', 'b', 'c' );

Now, given that @foo = ( 'a', 'b', 'c' );, it would seem logical
to me that the following two lines do the same thing:

$foo = ( 'a', 'b', 'c' );
$foo = @foo;

However, they don’t. The first one takes the last element of the array and
assigns it to $foo. (What happens to the rest of the array? And why
would you do this?). The second, incredibly, assigns the length
of @foo to $foo. If I want the length of an array, wouldn’t it
be more logical to say something like “foo = length( array )” (which,
coincidentally, is the proper python syntax)?

This posting was not meant as a “perl sucks, python rules” rant. In fact, I
don’t think that at all. Perl is an exceptionally powerful language, and I do
enjoy writing perl code. In particular, if I’m doing anything involving regular
expressions or string manipulation, perl kicks python’s ass all over the place.
However, perl does not have the most intuitive syntax, and you can write
completely unintelligible “Martian code” very easily in perl. There’s even an
online contest called Perl Golf to
see who can write the smallest possible perl program to do a particular task
— entries to this contest sometimes contain less than 50 bytes. Good luck
writing anything remotely useful in python in less than 50 bytes. In addition,
python requires correct use of whitespace to control program flow. Now,
when I first learned this, my initial thought was “How stupid is
that?”, but I’ve since found that as long as you have a python-aware editor
(emacs works nicely for me), this is not a big deal. The only drawback is that
if you want to remove an entire section of code, you can’t just put if( 0 )
{
at the top and } at the bottom like you can in perl, C, or C++.
Well, you can add if 0: at the top, but then you have to
re-indent the entire block
you want to remove. Again, with the right editor, this isn’t a huge deal.

Bottom line: perl and python are both great languages, but I have found that
the perl syntax is less intuitive and therefore harder to remember than python.
Thus, I have more trouble reading old perl code than old python code.

Note: I’m going away on vacation tomorrow for a week, so if you add
a comment to this post and I don’t respond, I’m not ignoring you. I won’t be
back online until at least next Sunday (the 18th).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s