Perl to Python Journal

Background

I am using these pages as a journal of a few projects that I'm doing in my free time involving converting old Perl programs into Python programs. I decided to make the journal public in case anyone else felt like seeing how the Python programs were developed and how they differ from the Perl versions. Hopefully, it will also serve to encourage a few more coders (especially Perl hackers) to look into Python. Python is a great language; try it!

Introduction

Before I begin, I should probably record some background. In early 1998 I was going to need to parse some column-oriented text files for a project at my job. Being a newish UNIX user, I planned to learn awk and maybe sed since it would have been silly to do the whole project in C (the only computer language I could really claim to know at the time). My boss knew some Perl and suggested that I learn Perl instead. I borrowed the Llama book and spent a few days learning as much as I could about Perl. I found Perl to be a powerful and fun language. I used it off and on for a year.

The Other "P" Language

After about a year, I anticipated the need to do some GUI programming. I mentioned the existence of Perl's Tk interface to a co-worker. He suggested that I instead try Python and its Tkinter interface to Tk. When I finally had time to look at Python a few months later, I borrowed a copy of Programming Pyhton. I read through the tutorial Appendix E, and I've been using Python ever since. Maybe someday I'll update this section with a list of things that really turned me from Perl to Python.

What's the difference

I still program in Perl. I also program in Python. For most tasks, I choose Python. I find that I am able to write manageable and reusable components more easily when I'm using Python. Its module and object support is elegant and convenient. The core language is very simple and extremely clean. The standard library that ships with Python is simple to to use and easy to read. It provides many of the same capabilities as the standard Perl library provides.

My intent is not to create a language war. I still use Perl. I still like Perl. Please don't send me e-mail explaining how great Perl is. Use both languages extensively for a year or so, and then make your own decision. If you've never used Python seriously for a month or more, then you probably don't really know what I'm talking about. If you've used Perl every day for the past 5 years, then you probably don't understand my troubles.

My biggest problem with Perl is that I don't program in Perl full time. Since I do a lot of data analysis and deal with a lot of text and binary data files, I have to be comfortable with programming, but I often have to take long breaks from any given language. After a month-long break from programming in Perl and/or Python, I find it much easier to work with Python than with Perl. The core of the Python language is simple and easy to remember from one month to the next. Every time I come back to Perl, I have to go back to the docs again and again, trying to remember special cases and defaults. I often stumble over some little quirk that I've never encountered before. I'm sure that true Perl Hackers stop stumbling over the things that bother me in Perl. At the beginning of the Camel book, the authors say, "Perl is designed to make the easy jobs easy, without making the hard jobs impossible". I've just found that most of the time Python makes my easy jobs easier than Perl does without making the hard jobs any more impossible. Of course, if I recognize that a problem is easier to solve in Perl, I use Perl, but I must admit that I haven't written a Perl script from scratch that grew longer than 5 or 10 lines since I started using Python.

The General Procedure

I usually notice a few distinct steps in my Perl to Python translations. I'm not recommending these steps as some rigid scheme. If you've ever rewritten a program in a different language, then these steps will sound familiar. Most of the time, they're all jumbled up and done almost simultaneously.

The First Step: Understanding

The first step in converting any program from one language to another is understanding what the original program does. For a small program, it may be sufficient simply to read the program. For a larger program, it may help to run the program and see its output. If there's anything in the original code that I don't quite understand, I usually find a reference and look it up.

When dealing with a smaller program, It's especially important to understand every line of code. I'm always suspicious of tiny Perl programs. They often use some default behavior of builtin Perl functions to get the most done in the fewest lines of code. I typically use perldoc, the Camel book, and/or the Perl man pages at this step. I often learn something new about a dark little corner of Perl that I had never explored. (It seems that Perl has a lot of these.)

For a large program (whatever that means to you), it may be more efficient to run the program several times to get an idea of its input and output and any other side effects. Then skim the code to get a general idea of how the original code accomplished the task. I always try at least to skim the original program for clever ideas. I sometimes also find pitfalls to avoid by understanding the program's algorithms or comments (comments--what are comments?). When I'm translating a program, the problem I'm trying to solve has already been (paritally) solved. There's no need to reinvent the solution; I just recode the solution someone else found (assuming it's a good solution).

The Second Step: Translating

I have no experience with translating programs larger than a few thousand lines. I don't recommend a direct translation unless the Perl code is fairly short and straightforward. Note that Perl and Python idioms are often very different. Translating even a small Perl program directly into Python may result in a working solution, but it probably won't be very Pythonish. Sometimes I do a (nearly) direct translation just to make sure I understand what the first program is doing.

The Third Step: Pythonizing

Important note: Python programs that aren't very Pythonish tend to run much slower than the Pythonish ones.

For example, in many Perl programs, I have noticed that the programmer uses regular expressions throughout the code to manipulate strings instead of using string functions such as substr. In Python, strings are just immutable arrays of characters. Instead of translating a Perl program's regular expressions into Python regular expressions, it is often possible to use simple array slicing or the string module to accomplish the same task. This type of translation usually produces much faster code (not always faster than the Perl, but faster than a literal translation to Python of the Perl code.) It also produces code that is more Pythonish, and other Python programmers who use your code will thank you for it.

Step two and three are slways a simultaneous task for me. As I translate, I consider whether there's a better, more Pythonish way to do the same thing. For example, the Camel book states that "Perl has always been biased in favor of flat, linear data structures." Python doesn't have that bias. Perl5 has references to help Perl hackers to build more complex data structures, but there is a lot of Perl code that doesn't use references when it probably should. In Python, variables always store an object reference. Therefore, it is trivial to construct more complex data structures (not to mention classes) in Python. At this stage of the translation, I often try to improve the data structures of the original Perl code.

The Fourth Step: Expanding

As it says in the Camel book, "if you're determined to reinvent the wheel, at least try to invent a better one." There's a lot of Perl code at CPAN. If I can't find a Python program that does what I need to do, I sometimes look at CPAN to see whether there's a Perl solution. If I have to do much with the Perl program, I may eventually translate it to Python. Just to make the Python world a better place, I try to improve the program as I rewrite it. I fix bugs. I make the program more general module. Python provides a separate namespace for my code "for free." :).

Perl to Python Projects

Perl is currently much more prevelent than Python. It seems that every programmer I know has at least heard of Perl. More than half of them hadn't heard of Python (until I told them about it).

Since Perl is so ubiquitous, if a Python programmer cannot find a Python solution for his problem, he can often find a Perl solution at CPAN. When I'm in this situation, I try to determine how much effort I think I'll spend maintaining and modifying the Perl code. I often conclude that it'll take me more time to maintain Perl code that someone else wrote than it will take me to reimplement their solution in Python and to maintain my program.

Here is a list of my currently documented examples:


Last modified by Tom Bryan on June 27, 1999.