Chad Perrin: SOB

10 March 2006

The Problem With Perl

Filed under: Geek — apotheon @ 12:58

This is the first of several entries I’m going to write about what’s wrong with some programming languages I’ve run across. Oddly enough, I’ve chosen the language with which I’m most comfortable to attack first — Perl.

There are two things wrong with Perl:

  • List Processing
  • Object Oriented Programming

Perl’s problem with list processing is pretty simple, really. Lists don’t nest. Period. If you stick a list inside another list, it’s unfolded into its discrete elements. As a result, instead of one list containing another, you end up with one list containing all the elements of another.

Perl has references, as a kludge to “fix” the list problem. It’s just not good enough. In general, Perl does everything better than PHP (it would be difficult to do them worse), but this is an example of something it does do worse than PHP. At least with PHP you can stick one list inside another. With Perl, you have to do gymnastics and become a contortionist to be able to roughly approximate the ability to nest one list inside another.

With Perl, pretty much everything is easy — except list processing.

Perl was designed as a procedural language. Object-oriented Perl is an afterthought. It’s a pretty broken afterthought. At a glance, it looks “not bad”, but that’s mostly because many programmers think of Visual Basic and C++ as object-oriented languages. Perl’s object oriented features are about on par with C++ (a hair less good for serious OOP), and notably better than VB’s object oriented programming features. OOP might have been tacked onto a procedural language as an afterthought, but at least it wasn’t tacked onto a line-oriented programming language as an afterthought, as happened in VB.

Still . . . you don’t really need object orientation to get things done. Sometimes it helps. Sometimes it doesn’t. When it helps, Perl’s object system is sort of a bad way to go about it.

There are a lot of other things people tend to think are broken in Perl, but as far as I’ve been able to determine the truth is that they’re just things that don’t suit the way these critics think. If Perl doesn’t suit the way you think, use a different language. That doesn’t mean the language is wrong, though — just as a jacket that is three sizes too large or too small for you isn’t wrong. It just fits someone else better.

I suppose there’s one other thing wrong with Perl. It doesn’t come with a compiler for creating optimized binary executables. In general, of course, it’s better off using its current just-in-time compiler, but once in a while it would be nice to be able to create a binary executable, and while it’s nice that it often outperforms Java’s VMs, it would be nicer if it could compete with some of the established traditionally-compiled languages.

9 Comments

  1. Good thoughts. I had the same impression of the OOP features of Perl — a “tack-on”. Ruby definitely does both OOP and lists better than her older sister.

    Comment by Sterling Camden — 10 March 2006 @ 05:15

  2. List processing — have to say you’re nuts on this one. Refs aren’t a kludge, they are The Path to Righteousness. I’m not sure why exactly you want to put a list inside another, or how you want it distinguished, but putting an arrayref as an element of an array is a perfectly good way to do it. The ref() function tells you whether the element you have is an arrayref or something else. If you want to loop over the whole list without having to write branches into every loop, just make an Iterator for the list.

    Maybe if you explained what you want here I could tell you how you need to adjust your thinking. Perl does tend to punish you if you don’t think the way it does. After a while you realize it’s right.

    You’re right about OOP, though. Definitely bolted on afterward. For all that, it’s not too bad functionally speaking, and even aids some things that are difficult in other OO implementations (creating methods dynamically or on demand, using a variable as a method name to call). But some things are definitely missing. “All this will be fixed in Perl 6.”

    There are really only two benefits of Perl generating a binary executable: avoiding compilation time, and code obfuscation. Perl compiles so quickly that it hardly matters. If you wanted to give up some compiler speed for code optimization, I shudder to think of the kind of tricky bugs that would be introduced by the two paths, plus I wonder how it would affect on-the-fly code generation. Obfuscation is generally not thought to be a worthy goal by Perlers (especially considering how easy it is to do that before compilation).

    Comment by sosiouxme — 10 March 2006 @ 05:28

  3. Refs aren’t a kludge, they are The Path to Righteousness.

    They’re a kludge as a replacement for actually nesting lists — and sometimes, that’s just a better option. Sure, passing by reference is better a lot of the time, but not all the time. For the most part, one of Perl’s strengths is the fact that it allows you to do whatever you need to do, however you want to. This is one instance where it seems to be taking a more Python-like approach of having a “One True Way”, and thus making life occasionally quite difficult.

    I’m not trying to do anything in particular at the moment. This was a meditation about Perl functionality in general, not a gripe about a problem with something I’m trying to do today.

    Perl does tend to punish you if you don’t think the way it does. After a while you realize it’s right.

    I thought this was Perl, not Python.

    aids some things that are difficult in other OO implementations (creating methods dynamically or on demand, using a variable as a method name to call)

    It’s because of things like that I said it was almost as good an OOP implementation as C++. It doesn’t even begin to touch OOP implementations on the level of Ruby and Smalltalk, though.

    “All this will be fixed in Perl 6.”

    I’m looking forward to that, actually. I think I’m going to edit the article to specify that this refers to Perl as of 5.8.x rather than Perl in perpetuity. From what I’ve heard, Perl 6 is going to be a huge step forward for Perl’s OOP capabilities. I wonder how it’ll stack up to Python after that.

    There are really only two benefits of Perl generating a binary executable: avoiding compilation time, and code obfuscation. Perl compiles so quickly that it hardly matters.

    Perl’s parser is blazing fast, to be sure, but being marginally faster than Java’s VM isn’t what I’d call fast enough that “it hardly matters”. A compiled binary from C that does the same things makes Perl look like it hasn’t gotten out of bed yet.

    In addition, there’s one other reason for a persistent executable binary that comes immediately to mind: distribution. Many people simply don’t have perl installed (I’m talking about Windows users here, mostly). Executable binaries have the advantage of not needing an installed programming tool (or six) to be useful to end-users.

    As for code obfuscation — I’m happy to never obfuscate code. It’s true that’s a potential use of a binary executable file, but it’s not a use I’m likely to need.

    print substr(“Just another Perl hacker”, 0, -2);

    Comment by apotheon — 10 March 2006 @ 06:09

  4. You can’t beat the ease of nesting lists in Ruby. Ruby makes it simple because a list is just an object, and an element of a list can be any type of object. No need to designate a “reference” to an object, because the only way you can access an object in Ruby is by reference. Even Java and C# have that part right. Ruby goes one better by providing syntax for ad hoc nested lists: [[x, obj], [[1,2,3],me,too]]

    Comment by Sterling Camden — 10 March 2006 @ 06:54

  5. PHP makes it quite easy to nest lists as well: an array is just a variable, and you can stick variables into other variables willy-nilly. That causes some problems, however, that Ruby’s approach does not. It’s not by any stretch an approach that I’d recommend in general, without something as smooth as Ruby’s object system undergirding it, but it does illustrate how Perl falls a touch short in regards to ease of list handling at times.

    One of the many mottos of Perl is “Make easy things easy and hard things possible,” or something along those lines. Forcing one to pass lists by reference strikes me as forcing one to do an easy thing in a difficult way.

    Comment by apotheon — 10 March 2006 @ 07:45

  6. Without an example it’s hard for me to see what’s hard about nested lists in Perl. The example the other poster gave from Ruby works almost verbatim in perl:

    my $listref = [[$x, $obj], [[1,2,3],$me,$too]]; for ( @$listref ) { … }

    Now granted, if you want to flatten the list that’ll involve writing your own recursion, but I just don’t see this as a big deal.

    My point about compiling: 1) The time taken to compile currently is so small it’s not worth saving; and 2) By compiling to something lower-level than a VM, you’d make it awfully hard to keep other dynamic properties, like the ability to construct and compile code on the fly.

    Now, I see your point about distribution. On the other hand, Perl is free — just distribute it along with the program. Easier said than done, I suppose :-) This will be true of any interpreted language… are there any that actually create a compiled binary to run independent of the interpreter/VM?

    Comment by sosiouxme — 11 March 2006 @ 05:49

  7. Perl’s problem with list processing is pretty simple, really. Lists don’t nest. Period. If you stick a list inside another list, it’s unfolded into its discrete elements. As a result, instead of one list containing another, you end up with one list containing all the elements of another.

    Perl has references, as a kludge to “fix” the list problem. It’s just not good enough.

    Another way to deal with certain types of lists of lists is with a multidimensional array. Behind the scenes, it’s just a list of refs, but for certain types of problems they can be significantly easier to use than other types of list constructions. See the first section of http://www.unix.org.ua/orelly/perl/prog3/ch09_01.htm, Arrays of Arrays. I always found that for functional programming, Perl objects were pretty flexible, albeit easy to get wrong unless you’re familiar with pointers the complex syntax rules. In certain applications, Perl data types are not as powerful as Lisp lists or C-style structs, but for common use, the inbuilt types (especially hashes) are much more useful.

    If you haven’t already read “Perl Objects, References and Modules” by Randal L. Schwartz and Tom Phoenix, I highly recommend it. It really helps to clear the mud.

    Comment by scoth — 13 March 2006 @ 11:54

  8. If you happen to have a copy of Perl Objects, References, and Modules that you could loan me at some point, I’d love to read it. Otherwise, I’m afraid I’m just not going to get around to reading it any time soon.

    Comment by apotheon — 14 March 2006 @ 12:09

  9. I do have a copy. I use it for reference from time to time though, so if you don’t have enough time right now to finish a book of 196-information-packed pages in a month or so, I’d rather wait until a more opportune time to loan it to you. I’ll bring it to NCLUG tomorrow in case you want to borrow it.

    Comment by scoth — 14 March 2006 @ 12:52

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

All original content Copyright Chad Perrin: Distributed under the terms of the Open Works License