Why I won’t learn Perl (voluntarily)
Posted by thepythonista on 2 June 2008
In comp.lang.python, Perl is sometimes referred to as “that other P-language.” Sometimes it seems as if people are afraid to speak its name.
In spite of the title, this post isn’t specifically going to be about Perl. Rather, I’d like to talk a bit about programming languages in general, and, specifically, the characteristics of programming languages that I like.
Over the years, I’ve learned (and liked), to various degrees:
- Python (obviously),
- C,
- Mathematica,
- Scheme, and
- Ruby.
This is counting only the general-purpose programming languages I’ve used. For example, HTML and LaTeX don’t count here. I’ve also tried (and disliked):
- C++,
- Haskell, and
- Common Lisp.
The question is: what do these two groups of languages have in common with each other? I think I know the answer. Haskell, C++, and Common Lisp seem to be “big” languages, while Python, et al. seem like “smaller” languages.
“Small” vs. “Big” Languages
Let me clarify what I mean by “big” and “small.” A “small” language is one that makes me keep a small number of concepts in mind in my head at a time, whereas a “big” language is one with lots of crooks and crannies to navigate
Under those definitions, I don’t think it’s hard to argue that C++ and Common Lisp are “big.” I don’t think Haskell itself is a “big” language, but, being un-used to it, I find I have to keep a lot of concepts in my head that I wouldn’t have to bother with if I were using, say, Python or Scheme. I suspect that more experience with the language would reduce this sort of cognitive burden I feel when trying to use Haskell, but, for now, I’m placing it in the “big” language category.
On the other hand, Scheme (at least pre-R6RS) is nearly the picture of minimalism, due to its academic pedigree. If you ignore macros (and I’m not saying you should if you want to learn Scheme), Scheme imposes almost no syntax on you, and its execution model is based on precisely one fundamental concept: the continuation. (Granted, it’s a somewhat mind-bending concept, but, once you get it, you realize it’s actually quite simple.)
The C language (as opposed to the C library) is likewise fairly simple. Its syntax can be described in about a page or so, and its execution model is essentially “all the world’s a PDP-11.” (This is an exaggeration, but not much of one.) If you’ve read K&R, you know it’s possible to write some extremely elegant and terse code in C. When I have to do some low-level bit-twiddling, or the performance of my Python code is insufficient, C is my weapon of choice.
Python also seems like a “small” language to me, because of the explicit philosophy of “there should be one (and only one) obvious way to do” any given thing. Although Python’s formal grammar is somewhat large, some of that complexity comes from the syntactically significant indentation. If we ignore any complications from significant whitespace, it’s still a little larger than C as a language, but not by much. Python benefits a lot from being approximately the level of the “not quite a real programming language” pseudocode one sees in algorithms textbooks.
On the other hand, I’m not exactly sure about Mathematica and Ruby. I’ve only dabbled a little in Ruby, but it sure seems like fun. Based on my limited experience with it, I’d have to say Ruby is a significantly larger language than Python. I’m going to withhold much of an opinion on Ruby until I get more experience with it.
As for Mathematica, its strength lies in one specific domain: numerical and mathematical (symbolic) calculation. I’m not sure if it’s a large language or not; the base language seems a lot like a Lisp without macros. What I do know is that it has an excellent library of functions for dealing with mathematics. I’ve found that if I can’t get the job done with Mathematica on a mathematics-oriented problem, either I’m going about it the wrong way, or the problem just can’t be solved in a reasonable time given the constraints of hardware I have to work with.
Perl
Okay, I suppose I’d better say something about Perl, since I mentioned it in the title. Perl 5, based on the little I know about it from secondhand rumours and innuendo, seems like one of the worst “big” language offenders. Every operator means something different, based on the context, and there’s no rule you can use to figure it out. You just have to memorize the permutations. When I’m programming, I don’t want to be carrying around that kind of cognitive burden; I want to use most of my brainpower on solving the problem at hand.
Perl’s philosophy of TMTOWTDI really grates on me here. Sure, on the surface, it seems like a good philosophy, because it gives the programmer flexibility to accomplish his goal. On the other hand, it makes reading other peoples’ Perl code significantly harder. Given the same exact algorithm, no two Perl programmers are likely to produce similar code. The computer has no trouble dealing with this, however, human readers of such code do.
I’m not even going to talk about some of the features of Perl that just seem wrong to me, like the fact that lists are automatically flattened by default. I’m not going to expound on how Perl encourages people to write cryptic code. I don’t even care about that right now. All I want to establish right now is that the Perl language is probably too big for my limited cranial volume.
Other “Big” Languages
Much the same criticism could easily apply to heavily macro-laden Lisp/Scheme code, as well. I’m not going to hold that against Lisp, because even experienced Lisp programmers concede the point. As Andrew Dalke said in the tutorial for python4ply (which, BTW, I really want to play with a bit):
[M]any experienced Lisp programmers will caution against the siren call of macros. Don’t make a new language unless you know what dangerous waters you can get into.
Judicious use of macros, OTOH, can really clarify the code in Lisp or Scheme. That’s why I’m not holding it against these languages.
Although, again, I claim a certain level of ignorance here, Perl 6 looks to be headed down the same road as its predecessor. One of the big dangers is that Perl 6 is going to give the programmer the ability to modify the grammar of the language. Granted, this is exactly what Lisp macros allow one to do, but Lisp (or, at least Scheme) sans macros is nearly simplicity incarnate.
Coda
Hopefully, if you’ve read this far, you’ve realized that the title of this post is merely a rhetorical device. I admit complete ignorance when it comes to Perl. Seriously — I don’t know crap about it beyond what I’ve read. Rumour and innuendo, that’s all. So, if I’ve said anything utterly stupid, I’d welcome a correction — post a comment.
Lee Aylward said
Perl operators do not behave differently based on context, they enforce a context on variables. For example, + only adds two numbers together, and will always return a number. When used on an array, + will force the array into scalar context.
my @a = (1,2,3);
my @b = (4,5,6);
@a + @b; # returns 6
Python, on the other hand, does have operators that behave differently based on context. In Python + can return a list, number, or string based on the context.
a = (1,2,3)
b = (4,5,6)
a + b # returns (1,2,3,4,5,6)
I don’t normally defend perl, but your critique of it’s operators seems to describe python more than perl.
thepythonista said
Lee,
Thanks for your comment. In fact, it’s the first official comment on my blog.
I see I was a bit misinformed about Perl operators. Nonetheless, I think the main point about Perl being a large language still holds. Do you agree?