How I learnt to love Perl(dmclaughlin.com)
dmclaughlin.com
How I learnt to love Perl
http://www.dmclaughlin.com/2008/12/07/how-i-learnt-to-love-perl/
8 comments
Interesting that you should complain about Perl, then say that you've moved to Ruby, because in my opinion, Ruby is no better constructed than Perl. The biggest crime I see attributed to Perl -- flexible syntax -- applies to Ruby in spades. (Ruby's actually much worse, since it allows you to do obtuse metaprogramming tricks that would make a good Perl coder blush. Not to mention the fact that it's a LOT slower.)
I think the main difference is that Perl is old, and Ruby is new. Geeks are a cantankerous, competitive bunch, and it's harder to be the hot new guy with mad skillz if you're working in a well-established language that has a huge base of expertise and good programmers. As a result, lacking outside pressures, programmers will always migrate to the flavor of the week, so that they can stand out from their competitors.
I think the main difference is that Perl is old, and Ruby is new. Geeks are a cantankerous, competitive bunch, and it's harder to be the hot new guy with mad skillz if you're working in a well-established language that has a huge base of expertise and good programmers. As a result, lacking outside pressures, programmers will always migrate to the flavor of the week, so that they can stand out from their competitors.
Ruby gets the basics of object oriented programming right. You should not have different syntax for different object types. In Perl, even for things like assigning to a variable or passing an argument to a function you need to know the types. It is nearly impossible to replace a list or a hash table for another datatype later. Ruby gets the simple stuff like this right.
Ruby's way of doing things is not necessarily "right". It's different.
In particular, if your fundamental types are fundamentally different, there's a strong argument that they should have different interfaces. Object-oriented programming does not require that all types be polymorphic, and pretending that they are is a source of confusion.
In particular, if your fundamental types are fundamentally different, there's a strong argument that they should have different interfaces. Object-oriented programming does not require that all types be polymorphic, and pretending that they are is a source of confusion.
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:
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.
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.
When you're passing parameters to a subroutine in Perl, all you're doing is passing a list. Not an array, but a list. The foo subroutine you posted, just wouldn't be written in Perl.
Besides, have you seen the syntax for passing arrays in PHP? Zend Framework is fugly:
Besides, have you seen the syntax for passing arrays in PHP? Zend Framework is fugly:
protected static function _assembleRoutes()
{
$routes = array();
$routes['entry'] = new Zend_Controller_Router_Route_Regex(
"[0-9a-z._!;, \=\-%]+-(\d+)",
array(
'module' => 'default',
'controller' => 'entry',
'action' => 'view'
),
array(
'id' => 1
)
);
return $routes;
}
10 lines to create an object = foo($bar);The foo subroutine you posted, just wouldn't be written in Perl.
I think I said that, didn't I? What I wrote is wrong, absolutely. I believe the correct thing to do is to either learn all about Perl references and dereferencing syntax so that you can pass lists of references to your Perl subroutines... or to switch to a different language. The history of PHP tends to suggest that most people pick Option Two.
PHP is a bad language filled with poor design choices. It is worse than Perl on every level except readability and learnability. Unfortunately, readability and learnability turn out to be very, very important. That's my only explanation for why PHP has crushed Perl in the web-language marketplace. (It's not as if Perl didn't have a big head start.)
I find myself working as a professional PHP programmer. But I, too, cannot find it in myself to love the example that you have posted. To pick on just one aspect: I am sick and tired of typing array() all the time. When PHP was mining Perl for ideas, couldn't they have chosen [] or {}?
And, yet, though I don't like the fact that your PHP example is 10 lines long and full of cruft, at least I can read it. I understand it. It is built out of very simple pieces, not the least of which is that damned array() syntax, which is used everywhere and which every PHP programmer learns to understand right away.
Let me ramble on about array() for a bit, because I often ponder it, as one might ponder Picasso's Guernica. The designers of PHP seem to have been so dead-set on making its datatypes simple (at least until they made two separate attempts to bolt on Java's ugly-ass class system, but don't get me started on that...) that (except for classes) PHP only has one non-scalar data structure, array(), which serves as both a hash and an array. This is an astounding design decision. On the one hand, PHP arrays are the centerpiece of my dislike for the language, because their semantics are just crazy. I complain about Perl's semantics, but PHP is unreal: Calling the wrong function on an array will transform all its string keys into arbitrary integers, or renumber your integer keys without telling you. You have to learn two ways to concatenate arrays: The one that turns all your keys into integers (discarding their original contents), and the one that doesn't. Or, consider: Until you explicitly sort it, a hash has an implicit sort order that is independent of the keys or values in the hash, but depends only on the order in which the elements were originally inserted. It's very quirky.
And, yet, I have to ask myself: Perhaps this only seems nuts to me because I learned Perl first. Perhaps newbies love the PHP array(), because when they see a variable they know that it is either a scalar or an array -- and, if it is an array, they know what to do with it! They don't have to worry about the distinction between an array and a hash. They don't have to worry about accidentally passing a hash to something that wants an array. The foreach() syntax is always the same. You see, the array may be a crappy data structure, but it is our crappy data structure, and OMG Alan Perlis was right even about PHP:
It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures. -- Alan Perlis
Is this insane? Yes. But there has to be some reason why PHP is such a success.
I think I said that, didn't I? What I wrote is wrong, absolutely. I believe the correct thing to do is to either learn all about Perl references and dereferencing syntax so that you can pass lists of references to your Perl subroutines... or to switch to a different language. The history of PHP tends to suggest that most people pick Option Two.
PHP is a bad language filled with poor design choices. It is worse than Perl on every level except readability and learnability. Unfortunately, readability and learnability turn out to be very, very important. That's my only explanation for why PHP has crushed Perl in the web-language marketplace. (It's not as if Perl didn't have a big head start.)
I find myself working as a professional PHP programmer. But I, too, cannot find it in myself to love the example that you have posted. To pick on just one aspect: I am sick and tired of typing array() all the time. When PHP was mining Perl for ideas, couldn't they have chosen [] or {}?
And, yet, though I don't like the fact that your PHP example is 10 lines long and full of cruft, at least I can read it. I understand it. It is built out of very simple pieces, not the least of which is that damned array() syntax, which is used everywhere and which every PHP programmer learns to understand right away.
Let me ramble on about array() for a bit, because I often ponder it, as one might ponder Picasso's Guernica. The designers of PHP seem to have been so dead-set on making its datatypes simple (at least until they made two separate attempts to bolt on Java's ugly-ass class system, but don't get me started on that...) that (except for classes) PHP only has one non-scalar data structure, array(), which serves as both a hash and an array. This is an astounding design decision. On the one hand, PHP arrays are the centerpiece of my dislike for the language, because their semantics are just crazy. I complain about Perl's semantics, but PHP is unreal: Calling the wrong function on an array will transform all its string keys into arbitrary integers, or renumber your integer keys without telling you. You have to learn two ways to concatenate arrays: The one that turns all your keys into integers (discarding their original contents), and the one that doesn't. Or, consider: Until you explicitly sort it, a hash has an implicit sort order that is independent of the keys or values in the hash, but depends only on the order in which the elements were originally inserted. It's very quirky.
And, yet, I have to ask myself: Perhaps this only seems nuts to me because I learned Perl first. Perhaps newbies love the PHP array(), because when they see a variable they know that it is either a scalar or an array -- and, if it is an array, they know what to do with it! They don't have to worry about the distinction between an array and a hash. They don't have to worry about accidentally passing a hash to something that wants an array. The foreach() syntax is always the same. You see, the array may be a crappy data structure, but it is our crappy data structure, and OMG Alan Perlis was right even about PHP:
It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures. -- Alan Perlis
Is this insane? Yes. But there has to be some reason why PHP is such a success.
We're getting down to personal choices here. What you think is readable depends on how well you understand the language. Some people don't like sigils, which Perl uses in abundance.
Taking a look at your PHP example, you have:
function foo($bar, $baz, $quux = array('quux' => "default")) {
What is $baz supposed to be here? I have no way of knowing that it's supposed to be a scalar, array or associative array.
The strength of sigils for readability is revealed in the equivalent Perl code:
my ($bar, @baz, %quux) = @_;
Here I know instantly, without reading any further documentation, that this subroutine expects a scalar (which in OOP would be the current object instance), an array and then a hash. It took a while, but I find this readable.
What PHP has over Perl, and indeed every other language right now is lowest-barrier-to-entry for web development. Out of all the other languages, it's the only one designed for the web.
On top of that, developing Perl ,Python or Ruby on a Windows machine is NOT fun and it's not easy. You want to play with PHP? Wampserver or Xampp can get you up and running on XP and Vista in seconds. Even if you manage to set up a Perl environment, you've still got CGI and DBI to install before it matches what PHP does out the box. Already I've installed Strawberry Perl, Apache, mod_perl and standard CPAN modules and all I wanted to do is a simple contact me form on my website!
That's why PHP is such a success.
Taking a look at your PHP example, you have:
function foo($bar, $baz, $quux = array('quux' => "default")) {
What is $baz supposed to be here? I have no way of knowing that it's supposed to be a scalar, array or associative array.
The strength of sigils for readability is revealed in the equivalent Perl code:
my ($bar, @baz, %quux) = @_;
Here I know instantly, without reading any further documentation, that this subroutine expects a scalar (which in OOP would be the current object instance), an array and then a hash. It took a while, but I find this readable.
What PHP has over Perl, and indeed every other language right now is lowest-barrier-to-entry for web development. Out of all the other languages, it's the only one designed for the web.
On top of that, developing Perl ,Python or Ruby on a Windows machine is NOT fun and it's not easy. You want to play with PHP? Wampserver or Xampp can get you up and running on XP and Vista in seconds. Even if you manage to set up a Perl environment, you've still got CGI and DBI to install before it matches what PHP does out the box. Already I've installed Strawberry Perl, Apache, mod_perl and standard CPAN modules and all I wanted to do is a simple contact me form on my website!
That's why PHP is such a success.
I agree that sigils are quite nice for readability. But haven't we established that this:
(I believe, in my own Perl, I used to work around this issue by using a lot of objects to encapsulate my hashes and arrays.)
Correct me if I'm wrong. I was never the world's most expert Perl programmer, I haven't used the language in several years, and Perl may have improved since I left.
---
[1] Not that there isn't more than one way to do it.
my ($bar, @baz, %quux) = @_;
while nice and readable, also isn't valid Perl? Because you have to pass references to get both an array and a hash into a Perl subroutine. So doesn't the actual Perl code look something like this? [1] my ($bar, $baz, $quux) = @_;
...and then, in the function, you have to remember to say @$baz because $baz is an array reference and %$quux because $quux is a hash reference? And then we have much the same readability problem as PHP, don't we? Except that the PHP programmer has to make fewer guesses, because the language has one fewer fundamental datatype. ;)(I believe, in my own Perl, I used to work around this issue by using a lot of objects to encapsulate my hashes and arrays.)
Correct me if I'm wrong. I was never the world's most expert Perl programmer, I haven't used the language in several years, and Perl may have improved since I left.
---
[1] Not that there isn't more than one way to do it.
This is somewhat of a contrived example. I can't think of any subroutine in perl that I've written, or interfaced with, or seen in production code, that takes multiple types beyond the first argument. If any function is doing that, the function is too complex and should be refactored. What you do see a lot of is stuff of the forms:
sub foo {
my($someflag, @subjects) = @_
sub foo {
my($self, %options) = @_
sub foo {
my($positional, %named) = @_
etc. And in fact, when the way you call these is the 90% case for functions, at least in perl. sub dosomething_with_data(@) { ... }
@data = (1, 2, 3);
@moredata = (4, 5, 6);
dosomething_with_data(@data, @moredata);
sub invoke(%) { ... }
%common_opts = (a=>1, b=>2);
invoke(%common_opts, c=>3);
invoke(%common_opts, c=>6, d=>5);
%overrides = (b=>3);
invoke(%common_opts, %overrides, c=>6);
(I included the subroutine prototypes for clarity). In this case, perl is exactly DYIM without the programmer having to think about list folding, array splicing, or hash merging. It just works. This would appear to be true dynamic typing, rather than dynamic typing where I still need to be strict about how I handle the values.I'm not sure that example, which doesn't do what it looks like it might do, supports your argument. Because
sub foo {
my($bar, @baz, %quux) = @_
Is just another way to declare your types: void foo(int bar, void *baz[], hash_t quux) { ...
Or in your untyped, dynamic language du jour with my bastardized Hungarian Notation: sub foo(Ibar, Abaz, Hquux) ...
However, as you point out, that syntax doesn't work because non-scalars need to be passed as references. Most non-scalar types need to be passed as references in C also (I can't remember which C standard let structs be passed as value), which is perl's heritage.Yes, if you want to write C this sort of thing is the least of your problems. Perl is certainly simpler and easier to learn than C. I'd also agree that Perl's declaration syntax is simpler than Java's, but what isn't simpler than Java's type system at this point? ;)
The simple syntax works in multiple Perl alternatives: PHP and Ruby are the ones I know about. Both languages have intelligent defaults to eliminate the need, in many cases, for newbs to think hard about what they're doing. (By default, PHP passes an array of arguments, by value -- with hidden optimizations to avoid the overhead of excess copying. The PHP argument array may include entire arrays as arguments. Meanwhile, in Ruby everything is an object, so Ruby passes an array of object references.) These are the languages which constitute Perl's competition, today. (Along with Python, of course, which I am unfairly leaving out of my argument because but I don't know how Python handles arguments! But I'm sure the answer is "with reasonable intelligence".)
The simple syntax works in multiple Perl alternatives: PHP and Ruby are the ones I know about. Both languages have intelligent defaults to eliminate the need, in many cases, for newbs to think hard about what they're doing. (By default, PHP passes an array of arguments, by value -- with hidden optimizations to avoid the overhead of excess copying. The PHP argument array may include entire arrays as arguments. Meanwhile, in Ruby everything is an object, so Ruby passes an array of object references.) These are the languages which constitute Perl's competition, today. (Along with Python, of course, which I am unfairly leaving out of my argument because but I don't know how Python handles arguments! But I'm sure the answer is "with reasonable intelligence".)
"but what isn't simpler than Java's type system at this point?"
Haskell's type system. ;-)
Haskell's type system. ;-)
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).
You can parse Perl with PPI (look at your nearest CPAN mirror).
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).
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).
[deleted]
It also doesn't help that the semantics of Perl leads to some difficult to read code even if it is well written.
php became popular because it is easy to install and requires almost no configuration post-install. for ISPs it was a no-brainer compared to the relatively complex mod_perl install
I'm not sure this is really true, when PHP started to gain popularity most hosts had a default cgi-bin with perl ready to go.
The popularity of PHP has much more to do with ease of use for users then admins.
The popularity of PHP has much more to do with ease of use for users then admins.
"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.
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.
Interesting. I did not know that British English uses "learnt" for the word "learned" in American English.
I think the lesson of this post is learn to use your tools well, despite how you feel about them.
quitting a difficult situation isn’t really in my make up.
Neither is humility, judging from this blog post.
Neither is humility, judging from this blog post.
I wish the author of this article had learnt to spell...
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.
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.
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.
"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.
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.
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...
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.
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...
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.
"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.
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.
Isn't git's porcelain mostly Perl and shell scripts?
(...which is gradually being rewritten in C, I know.)
It does appear that the signal-to-noise ratio in the talent pool declines over time, for just about any popular programming language (other than C, possibly).
(...which is gradually being rewritten in C, I know.)
It does appear that the signal-to-noise ratio in the talent pool declines over time, for just about any popular programming language (other than C, possibly).
So... what happens when this guy finally learns of a well designed language like python? Does his head just explode?
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.
What things do you like better about Perl than Python? (honest question)
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:
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_abcdefghijklmnopqrstuvwxyzBetter python version:
print ''.join(chr(i) for i in range(256) if re.match(r'\w', chr(i))
Learn to use list comprehension.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:
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)))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.
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.
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:
I'm all for practicality but principles are condensed experience and it is dangerous to ignore them without a good reason.
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.
On my computer:
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.
$ 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.
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...
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/Technically, that's a generator expression. :-P
I didn't say I liked anything in Perl better than Python. There may be a couple of things, but it would just boil down to personal taste.
Conversely, I like Python better than Perl in two major departments though:
1) The way you import stuff in Python. If you have a long namespace in Perl you have to type it out every time you instantiate an object. Example:
use Organisation::Project::App::Models::Feature;
my $feature = Organisation::Project::App::Models::Feature->new();
In Python you would do: from organisation.project.app.models import feature;
feat = feature();
It's a small point, but when you have multiple views/actions inside a controller that all use the same model you start to get annoyed typing that namespace in Perl.
2) The native OOP system in Python is much easier than Perl. With Moose this is far less important than it used to be, but comparing core Perl to core Python it is an issue.
Conversely, I like Python better than Perl in two major departments though:
1) The way you import stuff in Python. If you have a long namespace in Perl you have to type it out every time you instantiate an object. Example:
use Organisation::Project::App::Models::Feature;
my $feature = Organisation::Project::App::Models::Feature->new();
In Python you would do: from organisation.project.app.models import feature;
feat = feature();
It's a small point, but when you have multiple views/actions inside a controller that all use the same model you start to get annoyed typing that namespace in Perl.
2) The native OOP system in Python is much easier than Perl. With Moose this is far less important than it used to be, but comparing core Perl to core Python it is an issue.
Yes its seems common for Perl libraries in commercial environments to get very long and come a right PITA ;-(
However check out the excellent "aliased" module... http://search.cpan.org/dist/aliased/
From its POD...
However check out the excellent "aliased" module... http://search.cpan.org/dist/aliased/
From its POD...
use aliased 'My::Company::Namespace::Customer';
my $cust = Customer->new;
use aliased 'My::Company::Namespace::Preferred::Customer' => 'Preferred';
my $pref = Preferred->new;CPAN strikes again, I was actually hoping someone would show me a better way when I posted that. So thanks!
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 ;-))