
 How I learnt to love Perl - prakash
http://www.dmclaughlin.com/2008/12/07/how-i-learnt-to-love-perl/
======
petercooper
_but these are all superficial next to the damage done by all the absolutely
atrocious Perl code out there._

The writer argues that Perl's being damaged by bad code examples, but if that
were the case, PHP would be the least popular language in the world, no?

Perl's troubles are not just because of bad code examples, because the
language is poorly constructed (in terms of v5, v6 is a lot better), or
because its marketing is poor/non-existent.. but because of _all_ of these
things and many other issues beside (especially the difficulty of deployment).
These issues are enough to make one jump ship after years of non-resolution.

(I was a nearly full-time Perl developer from 1996-2005 - haven't touched it
at all in the last few years since I jumped ship to Ruby, so it's not as if
I'm hating on the language without having once loved it ;-))

~~~
mechanical_fish
It's not that Perl examples are unusually bad. It's that Perl's syntax is bad.
Really bad. Especially for newbs.

Declaring a function in PHP which accepts a scalar, an array and a hash:

    
    
       function foo($bar, $baz, $quux = array('quux' => "default")) {
    

Declaring the same function in Perl:

    
    
       sub foo {
         my ($bar, @baz, %quux) = @_;
      

Which is already terrible. Worse, despite being relatively intuitive (I've
made the mistake of writing this more than once, whenever I forget too much
about Perl) it's completely broken. In the words of the Camel book:

 _If you want to pass more than one array or hash into or out of a function
and have them maintain their integrity, then you're going to want to use an
explicit pass-by-reference. Before you do that, you need to understand
references as detailed in Chapter 4. This section may not make much sense to
you otherwise. But hey, you can always look at the pictures._

Here we see that Perl's syntax isn't just very ugly: It's hopelessly entangled
with relatively-advanced concepts like references, and dereferencing, and
pass-by-value vs pass-by-reference, and wacky only-in-Perl nonsense like
"array context" vs "scalar context".

Even PHP can do arguments right. Meanwhile, Perl doesn't even apologize for
being a language where you have to learn about pointers before you can walk.

~~~
gaius
Hence the saying _only Perl can parse Perl_. Which is fine for 100-line
scripts but for 50,000 line projects written by many people over many years
(these exist!) it means you get basically zero tool support. Both Python and
Tcl scale much more cleanly from small one-off scripts to larger applications
(as well as any weakly dynamically typed language can, anyway).

~~~
SwellJoe
Our projects total about 450,000 lines of Perl code. I've worked on one large
Python project (SciPy), and found it similarly comfortable. I didn't feel
major pains going either direction (from Perl to Python or back to Perl
again).

I also spent some time with a large Tcl project (OpenACS) and found it very
painful. But, I've never learned Tcl with as much enthusiasm as I learned Perl
or Python, so I might be wrong. Actually maybe it's just CMS that really suck.
I hated spelunking in Zope, and I hate working with Joomla (for different, but
no less strongly held, reasons).

------
timr
_"I had always known of it but had shied away from it for so long because,
again, it didn’t follow the same rules as my comfortable PHP shared hosting
comfort zone."_

I'm pretty sure that this comment applies to 99.9% of all language complaints
I read on the internet. Even smart people have a tendency to bash what they
don't understand.

------
rkowalick
Interesting. I did not know that British English uses "learnt" for the word
"learned" in American English.

------
scott_s
I think the lesson of this post is _learn to use your tools well, despite how
you feel about them._

------
xiaoma
_quitting a difficult situation isn’t really in my make up._

Neither is humility, judging from this blog post.

------
jm4
I wish the author of this article had learnt to spell...

------
drwh0
all of this kvetching is pointless. if you use and like perl, the statistic
you really care about is the activity of CPAN, which continues to thrive. if
you like perl and are productive with it, why stop? because some moron on
hacker news says perl is "noisy"? if you stop using a tool you like because of
a blog post....get used to changing tools often, because "...is dying" is
popular with bloggers.

~~~
mechanical_fish
_if you like perl and are productive with it, why stop?_

To pick a rather extreme example, consider COBOL. COBOL is also not dead (I
know people who make a living writing COBOL) but it _is_ a tool which no young
programmer wants to learn, unless they have a _very_ specific personality or
the money is really, really good.

If you don't mind the fact that the talent pool is reportedly shrinking and
the price of finding talent is reportedly rising, then you're right: Perl
works as well as ever. (And much better than COBOL, of course. Perl will need
another thirty to fifty years to reach COBOL's current stage. It's still quite
pervasive, especially in its niche.) But if you pine for the glory days of
1995, when exciting new developments in computing were being constructed
primarily in your language, you will want to learn a language other than Perl.
Or, if you anticipate the need to expand your operation from two or three
talented coders to twenty or thirty, you might need a language other than
Perl.

~~~
SwellJoe
"But if you pine for the glory days of 1995, when exciting new developments in
computing were being constructed primarily in your language, you will want to
learn a language other than Perl."

This is exactly the sort of FUD the article seemed to be targeted at. Perl is,
currently, a more powerful language than Python or Ruby in several areas.

I happen to like all three languages, and have written significant code in
Python, but the Perl community is still very active and doing interesting
things (as the increase in contributions to CPAN indicates). It's just a more
mature community. When someone, say, writes an SMTP server in Perl, they don't
freak the fuck out and post a hyperbolic blog post about how freakin' awesome
it (and they) are...they merely upload it to CPAN, where it joins the dozen
other projects that do the same thing in different ways. If you consider all
of the catching up that's happening in the Ruby and Python worlds to be
"exciting new developments"--like mature testing frameworks, coverage
reporting, library packaging and management, deployment tools, Apache modules,
etc.--then, yes, you'd want to be working in a language that doesn't already
have excellent implementations of all of those things.

Of course, if the Perl community were content with what they currently have,
and weren't always pushing forward with newer/better ways to do things, it
would be just as bad. But, Moose, as the obvious (but not only) example,
should make clear that that's not the case.

"Perl will need another thirty to fifty years to reach COBOL's current stage."

I hope you'll remember this in two years. If it still seems likely to come
true after Perl 6, I'll buy you a beer.

~~~
mechanical_fish
_When someone, say, writes an SMTP server in Perl, they don't... post a
hyperbolic blog post about how freakin' awesome it (and they) are... they
merely upload it to CPAN._

I guess I wasn't clear enough, because I agree with that, and it is in fact
what I was trying to get at with my FUD-worthy sentence. Perhaps I should have
put "Exciting New Developments" in silly caps to emphasize that I was talking
about _hype_. If you want to work in a language that still has significant
hype, and _enjoys_ having hype, and doesn't try to make you feel dirty for
_practicing_ hype, you need to learn a language other than Perl. Until Perl 6
comes out, at any rate.

Your post does little to convince me that I'm wrong about that. :)

Personally, I like a little hype in my life. I tend to agree with Bruce
Sterling:

[http://www.viridiandesign.org/2006/03/viridian-
note-00459-em...](http://www.viridiandesign.org/2006/03/viridian-
note-00459-emerging.html)

 _Hype is a system-call on your attention. If hype is clearly aimed straight
at your wallet, you are right to worry. But hype is only bad for you if you
drink it unthinkingly, by the barrel and case. If you soberly track its
development, hype is very revealing. Even mistaken and obscurantist hype shows
that people are stupid and trying to hide something, which are always good
things to know._

 _In politics, the opposite of hype is political reality. Political hype is
BS, it's a campaign speech, it's meant to deceive the listener. But in
technology, the opposite of hype is not the truth. The opposite of hype in
technology is argot. It's techno-jargon. Argot is not reality, jargon is not
the truth. Argot is a super-specialized geek cult language that has no
traction in the real world. Argot is the deliberately hermetic language of a
small knowledge clique._

I do not doubt that Perl programmers are very smart, and that they are
constantly pushing the state of the art. I also do not doubt that Perl code
runs the world while other languages are frivolously reinventing new and
sillier forms of the wheel. (How can I? I wrote a bunch of Perl code that is
currently helping to run a factory. There is every danger that this Perl code,
though not a sterling example of its genre, will outlive me. I have a healthy
respect for Perl's usefulness.)

But I'm not convinced the language is reaching a lot of new blood. And that's
an important task -- perhaps the _most_ important task. They say that every
trick in software was invented by a Lisp programmer before I was born, and
they may be right. But, to the extent that this is true, that means that there
is relatively little to gain right now by making languages "more powerful".
The real win is to make powerful languages more clear and ubiquitous, and to
teach them to more people. And reaching people requires clarity, pedagogy...
and hype. You need to make a system call on their attention.

~~~
SwellJoe
"Your post does little to convince me that I'm wrong about that."

Quite right. I misinterpreted your prior post. Sounds like we agree, though
I'm curmudgeonly enough to think that much of the hype around some projects
and developers is laughable. The flavor of the week right now is Ruby, and a
few functional languages, but it happens everywhere.

In a lot of cases, projects are being celebrated for being fumbling, and often
baroque, attempts to solve problems that are already well-understood by
developers in other languages...and all they have to do to solve it equally
well in their own language is to pull their head out of their self-
congratulating ass long enough to see how it's been done before, learn from
it, and maybe even improve upon it a little bit.

Nonetheless, I must concur that hype is very effective...and probably
mandatory for the survival of a language. Tcl is probably an excellent example
of a pretty cool language, with a previously huge community, dwindling over
time due to lack of enthusiastic new proponents.

------
newt0311
So... what happens when this guy finally learns of a _well designed_ language
like python? Does his head just explode?

~~~
DavidMcLaughlin
Good to see you read the article. I already have a VPS set up running django
for my band website. Python is great, but Perl is great too.

~~~
jimbokun
What things do you like better about Perl than Python? (honest question)

~~~
d0mine
In Python there is no _one obvious_ place to go for 3rd party packages
(easy_install is a dwarf compared to cpan).

In Python there is no _one obvious_ documentation system (Sphinx, epydoc,
pydoctor, ...).

Syntax for working with regular expressions is not builtin in Python.

One-liners are useless in Python (due to whitespace sensitivity).

Chaining of expressions (in functional style) is more cumbersome in Python
than in Perl. Compare (from <http://www.hidemail.de/blog/perl_tutor.shtml>):

Print the canonical sort order in Perl:

    
    
       say sort grep /\w/, map { chr } 0 .. 255;

Literal translation to Python:

    
    
       print ''.join(sorted(filter(lambda c: re.match(r'\w', c), map(chr, range(256)))))

A more pythonic version:

    
    
       print ''.join(sorted(re.findall(r'\w', string.maketrans('', ''))))

Ruby version:

    
    
       puts (0..255).collect { |i| i.chr }.select { |c| c =~ /\w/ }.sort.join ''

Output:

    
    
       0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz

~~~
newt0311
Better python version:

    
    
       print ''.join(chr(i) for i in range(256) if re.match(r'\w', chr(i))
    

Learn to use list comprehension.

~~~
d0mine
1\. where is `sorted()`.

2\. where is closing `)`.

3\. DRY principle is more important than a couple of parentheses here and
there (there could be a heavier function than `chr()`).

And I _know_ list comprehension (and generator expressions, and dictionary
comprehension, and set comprehension).

One of versions I've considered for Python was:

    
    
      print ''.join(sorted(c for c in map(chr, range(256)) if re.match(r'\w', c)))
    

And even:

    
    
      print ''.join(sorted(c for i in range(256) for c in (chr(i),) if re.match(r'\w', c)))

~~~
newt0311
Sorted is unnecessary: the range function generates them in the right order.

The last ')' character is missing. Sorry about that. I have been spoiled by
show-paren-mode.

The DRY principle is great when applied to large swaths of code but in this
case, seriously, it is faster and more concise to just write it again. Either
the language optimizer will optimize out the extra work (not in CPython
though...) or it will not. Either way, your functions would be slower as they
have to explicitly allocate either two lists or a list and a tuple unless they
are optimized further, not to mention that the added structures will make
optimization challenging.

Principles are great in theory but try considering practical aspects once in a
while.

~~~
d0mine
The whole point of the example is to demonstrate that chaining of expressions
is cumbersome in Python, so imagine some other function instead of `sorted()`
and use it.

DRY is not about performance; it is about: I've changed here some code and
oops I've got a bug because I forgot (or didn't know or it is impossible to
decide whether it is the same code or not and therefore should we change it or
not) to change it in other places.

Performance:

    
    
      $ python -mtimeit -s"import re" "''.join(sorted(chr(i) for i in range(256) if re.match(r'\w', chr(i))))
      1000 loops, best of 3: 1.29 msec per loop
    
      $ python -mtimeit -s"import re, string" "''.join(sorted(re.findall(r'\w', string.maketrans('', ''))))"
      10000 loops, best of 3: 60.8 usec per loop
    

My variant is 20 times faster. However performance doesn't matter in this
case.

I'm all for practicality but _principles are condensed experience_ and it is
dangerous to ignore them without a good reason.

~~~
newt0311
On my computer:

    
    
       $  python -m timeit -s 'import re' '"".join(chr(i) for i in range(256) if re.match(r"\w", chr(i)))'
       1000 loops, best of 3: 841 usec per loop
       $ python -m timeit -s 'import re' "''.join(sorted(c for c in map(chr, range(256)) if re.match(r'\w', c)))"
       1000 loops, best of 3: 792 usec per loop
       $ python -m timeit -s 'import re' "''.join(sorted(c for i in range(256) for c in (chr(i),) if re.match(r'\w', c)))"
       1000 loops, best of 3: 921 usec per loop
    

Your DRY variants (against which my complaint was) are not faster.

As to the principle of DRY: Which is easier to debug? my code or your code?
mine is certainly easier to read. Principles are the _average_ of large
amounts of experience. Its never a good idea to ignore them completely but
just blindly following them without keeping in mind the context they were
formulated in is just as stupid.

PS: Your version with the re.findall is faster but requires the user to bring
up a definition of string.maketrans and re.findall, both things that an
experienced python coder would know but its another little thing that they now
have to track. OTOH, the generator expressions (especially mine) are
straightforward and blindingly obvious as to their purpose.

~~~
draegtun
I find the Perl and especially the Ruby versions are a bit easier to read than
any of those Python examples.

If u like left to right chains then Perl can also be written like so...

    
    
      use autobox::Core;
    
      say [ 0..255 ]->map( sub { chr } )->grep( sub { m/\w/ } )->sort->join('');
    
    

/I3az/

