So I learned Python the other day.
Actually, that’s a joke. You can’t learn a programming language in a day. But if you already know several others, you can learn the basics: the syntax, looping constructs, how variables work, things like that. Enough to write simple scripts while checking the documentation for specifics on particular functions. Python has become ubiquitous enough that I figured I need to be familiar with it, if not expert, so I plowed through a tutorial.
I like it more than I expected to. The indentation-as-syntax thing doesn’t annoy me like it probably would have a decade ago. I’ve been using org-mode for a while now, so I’ve gotten used to hitting Tab to cycle through indentation levels in headings and lists. Doing the same in a Python script feels natural enough. The python-mode in Emacs usually guesses right anyway.
There’s always been a Perl vs. Python battle online, so I’m surprised how much it feels like Perl. Yes, the syntax is different, with no sigils on variables and indentation instead of curly braces for grouping statements. But that’s just surface-level stuff. Under that, they both feel like practical glue languages which have been extended to do classes and modules and other “serious” programming features, but are still at heart scripting languages. By a “glue language” I mean one that’s good at tying other tools together, especially taking output from one and processing it in some way before feeding it to another. Both languages are handy for knocking out short scripts for that kind of thing, or quick one-time filters at the command line.
Python, like many languages, uses Perl’s regular expressions, so that’s already familiar. It has list comprehensions which are like Perl-style postfix notation, so that these are the same:
#perl
say for (1..10);
#python
[print(x) for x in range(1,11)]
The python example is a bit more wordy, but when you consider that you can chain those and include IF statements, you can pack more into a Python statement sometimes. For example, print a list of all multiples of two two-digit numbers that are evenly divisible by both 5 and 7:
#perl
for my $y (10..99) {
for my $x (10..99) {
say "$y $x ".$y*$x unless $y*$x%7 or $y*$x%5;
}
}
#python
[print(x,y,x*y) for x in range(10,100) for y in range(10,100) if not x*y%5 and not x*y%7]
You can jam the Perl example into one line, because that’s always possible, but it won’t be as clean as that.
Perl feels more Unix-ish, since it got a lot of ideas from shell scripting and Unix utilities like awk and sed. It has built-in functions for interacting with Unix, like inter-process communication and functions borrowed straight from Unix C libraries like gethostbyname(). It feels like it was designed by people who were using it to get things done at the same time, so they pulled in features as they needed them. That gives it that “tie tools together to make tools” Unix feel.
Python feels more like it was academically designed, like it came from computer science experts rather than sysadmins and hackers. (I don’t know if that’s true; just how it feels.) It feels more Lisp-y somehow, which isn’t a bad thing. The Unix stuff that’s built into the core of Perl is in separate modules in Python. That means better organization and probably a leaner core interpreter, but you do have to learn what comes from where so you can import the necessary modules when you need them.
One difference is in the mottoes of the two languages. Perl’s is TMTOWTDI: There’s More Than One Way To Do It. While Perl programmers have settled on some best practices over the years, the language still lends itself to multiple ways to do almost anything, and Perl programmers like it that way. For Python’s motto, some have suggested TOOWTDI: There’s Only One Way To Do It. Again, that’s overly simplified, but the Python community does seem agreed that there should be one best way to do a task, and that best way should be obvious.
One blatant example of this difference in attitudes is Perl Golf, where programmers have competitions to write the shortest program possible to do a task. This usually means using special variables and weird tricks, and results in programs like this one. It looks like a string of nonsense, but it’s a real Perl program that takes a 24-hour time like 15:30 and prints out a clock face:
$c[$_*=.52,5.5-4.7*cos][8+7.4*sin]=$`%12-$_?$_^$'/5?o:'m':$_^$'/5?h:x
for<>!~/:/..11;print"@$_
"for@c
There have been some attempts to do Python Golf, but it doesn’t look like there’s much enthusiasm for it, and the language just doesn’t give you the freedom to be that insane.
As someone learning the language, I don’t mind Python’s lack of that much freedom. I don’t need to learn several different ways to do each thing; one way is plenty. And I think TMTOWTDI is one reason Perl has lagged in popularity and isn’t pulling in as many new programmers as it used to, though it’s still used constantly by sysadmins like me: there’s not a streamlined way to teach or learn it. It’s a dirty toolbox full of tools that do all sorts of different things, some very similar to each other, and you just have to dive in and tinker with them all until you figure out how to put them together in ways that work for you. Python is a clean toolbox with fewer tools that each do one clear thing, and if you ask three python programmers how to use them, they will all tell you pretty much the same thing.
Perl is still more suited to my just-hack-it-together day-to-day mode of thinking, but Python has potential for writing programs for others to use and understand. I don’t see as much conflict between them as I expected, and they fall into the same category of “handy scripting language” for me compared to a compiled language like C or something more abstract like Lisp.