What I like/dislike about Perl

bart on 2008-05-10T06:39:09

Inspired by jarich's post (and thus indirectly by brian_d_foy's request) and by a question on arrays on Perlmonks, I've made a list of things I particularly like or dislike about Perl. Sometimes, items in both lists can be caused by the same things, so these things are the result of a compromise, and I don't think they can easily be improved.

Note that these are things from the top of my head, so it's likely that I've forgotten about some stuff that I normally have a huge axe to grind with. So, here goes:

Likes about Perl:

  • Regexps! Hashes!
    Obviously, to me these were Perl's immediate selling points, 12 years ago.
    But, obviously, since then, many other languages have copied both features.
  • Simplicity/transparency of passing arguments to subs, using @_
    Data in @_ is "passed by reference", it's assigning to local variables that makes it "pass by value"
  • Flattening of lists: this makes join(', ', @foo, @bar) possible, and implementing a min function min that can be used both for min(@foo) and for min($x, $y, z)
  • scalar/list context
  • sort function, compared to the mess in PHP (array_multisort)
    Ease to implement Schwartzian Transform, or-cache etc.
  • regular expressions as first class objects, as opposed to languages where a regexp is a string, until you use it as a regexp (i.e. most of them)
  • interpolation (doublequotish strings)
  • garbage collection, using reference counting
  • general syntax: no obsession with uniformity of syntax, the "adapted to humans" ad hoc syntax of Perl generally works very well
  • transparency of implementation, introspection. Extending/modifying Perl from within Perl, is generally quite easy... For example: Hook::LexWrap, Carp, Fatal, Memoize
  • closures
  • map, grep
  • overload
  • The fact that "use" of a module happens on the Perl level, for example import, but also BEGIN (INIT, CHECK)
  • AUTOLOAD for possibly loading modules or generating subs on the fly

Dislikes:

  • nested subs and lexicals in the outer sub just don't work well together (DWIM? Are you kidding me?)

    What I really want, is the way it works in Javascript: inner subs are not visible outside the outer sub, and lexical variables from the outer sub are visible/accessible/shared in the inner subs

    The reason for how it works in Perl, is likely because a BEGIN block is a sub (you may even use the keyword "sub", though nobody does that), that's executed immediately and subs used in a BEGIN block must be considered as global subs.

    As a result, this makes implementing a framework similar to mod_perl, where a plug-in looks like a Perl script but is loaded from file once and next can be called many times, unnecessarily hard.

    Hate, hate, hate!

  • lack of formal parameters
  • complex data structures can be hard, confusion between array and array reference: ['a', 'b', 'c'] is called an "anonymous array" but actually it's an array reference The fact that Perl distinguishes between arrays and array references can be a good thing, but it has its disadvantages.
  • lack of proper native support for aliasing, for scalars you can fake it with for my $x ($y) { ... } and inside the block, $x is an alias to $y. There's no equivalent trick for aggregates
  • Passing arrays/hashes by a reference (of course) results in the need in the sub to access the hash in the sub through the reference. The above points make that not easy to remedy.
  • lack of clean way to interpolate functions/method calls in doublequotish strings, @{[...]} is a hack
  • constants, which are argument-less subs, and thus, you can't interpolate them in strings
  • need for $, @, % for variables in not-interpolating context (syntax pollution)
  • local doesn't work with lexical scalars -- it does work on individual items in arrays/hashes, even lexical ones.
  • lack of ordering in hashes, the implicit "same order as insertion order" in PHP/Javascript, and as implemented in the modules Tie::IxHash/Tie::Hash::Indexed, works very well for me.
  • for OO, lack of proper instance variables. Access to attributes is low level and look ugly like $obj->{x}. Direct access to with $x instead of $obj->{x} would be most welcome, even if only as syntactic sugar.
  • hard to parse syntax with tools If you can't modify Perl from within, it's virtually impossible to change it on the source level. Source filters are generally considered a poor idea, because the chance of getting it wrong, is huge.
  • lack of embedding of custom "small languages", like SQL. For example, for DBI, I'd really prefer it if the syntax of embedded SQL could be checked at compile time (maybe assuming a broad SQL syntax, even if this particular database doesn't like it). This is not practically feasible because of the previous point (hard to parse syntax / source filters bad).
  • Exceptions are a hack. "eval BLOCK" is a terrible name, only used because "eval STRING" also catches errors... so it's a historical choice, not functional It should have something like try/catch, or even the on "error goto ERRLABEL" from VB.
  • $SIG{__DIE__} is called in eval
  • no functional/chaining versions of s/// and tr/// (as in Javascript)

Hmm, and that off the top of my head... It has become quite a long list, actually.

update I knew I had to forget someting. So, without delay, the addendum:

Pro:

  • General execution speed (apart from a slight delay at startup)

Contra:

  • Memory footprint, even for tiny scripts: at least several megabytes. It's enough to have me often convert often run short scripts into another language with a much smaller footprint.