Saturday, March 10, 2007

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).

2 comments:

Unknown said...

Cool kids use ruby?
That explains why Google and Yahoo are populated by cool kids.
..
..
Oh wait, Google and Yahoo heavily use Python. My mistake. That means they must not be cool, despite dominating the majority of search engine choices.

Anonymous said...

Informative post, thank you.