Why I Use Perl: Reliability
modernperlbooks.com
modernperlbooks.com
And though I admit the culture is great overall, that does seem to be my experience with CPAN. You never know what you're going to get. It's like that to some degree with every language but with CPAN there's so much trust in the system it can be harder to identify and filter out the lesser quality stuff.
The other way to do it is to start an HTTP server locally and use that (which is what WWW::Mechanize does)
The whole point of automating tests is so you can run them unattended: at install time, or under a continuous integration system after code check-ins, or for git pickaxe to find which change caused a bug, or whenever else you want to confirm that a whole lot of code still works as intended.
Agreed :-)
And though I admit the culture is great overall, that does seem to be my experience with CPAN. You never know what you're going to get. It's like that to some degree with every language but with CPAN there's so much trust in the system it can be harder to identify and filter out the lesser quality stuff.
There are lots of nice tools that help with that though. https://metacpan.org/, http://cpantesters.org/, http://cpanratings.perl.org/, etc.
CPAN has had many more years than Ruby's Gems to mature and develop.
There are 2560 [edit: I was wrong. 39411 is the right number] gems on http://rubygems.org/. There are 24,920 distributions on CPAN. Well over 100k modules. The automated testing infrastructure, documentation, etc. also makes it much easier to figure out what modules work on what systems and what versions of perl than in ruby land. Things like meta.cpan.org and cpantesters.org are a god send that I wish I had when I'm using other languages.
And the testing infrastructure rocks.
It's evolved so everything produces and consumes TAP (http://testanything.org/) a simple human-readable protocol for expressing pass/fail results (with standard modules that help people output and consume TAP).
This means I can write tests procedurally, or in an xUnit style, or a BDD style, or a specification-based testing style, or use various DSLs for things like exception testing or for testing web apps... and so on.
I just use the style that seems most appropriate for the thing being tested. They all output TAP. All the standard test runners consume TAP. Everything "just works" and plays nice together.
I can even easily integrate tests running in other languages or environments as long as they output TAP.
In addition - since almost all of the Perl testing modules use a common TAP output module - you can usually integrate different styles in the same test code. So, if appropriate, I can pop some specification-based tests and some friendly web-testing DSL as assertions inside my xUnit tests.
Fun :-)
Wish other languages test environments were setup this way.
That makes it easy to use a cpan module with confidence, which imo is not valued highly enough in other language communities cpan-like structures.
I misunderstood the 39411 number to be the total number of gems submitted over all time, rather than the total number of extant versions. My bad.
Also the rspec ecosystem is becoming more and more mix-and-match.
It's nowhere near as integrated as perl yet though.
I find it interesting that PHP doesn't have anything in the same league as Perl/Ruby/Python even after all these years.
Any PHP folk out there?
Heh the worst upgrade experience I've had with any language was with perl. The issue wasn't with changes to language features, it was chaos resulting from CPAN XS module compatibility and compilation failures. I remember one trivial module (array::compare) went from a having few core dependencies to dozens of CPAN dependencies (including all the moose OO modules). And that was just one module, there was a list of others that had issues.
To be fair, that was a Solaris environment and was the only time I had issues that serious. But I'd argue documentation of dependencies is a much bigger factor no matter what the language.
"Hey, they just released a new major version of $LANGUAGE today. Can you go upgrade it on all our production servers?"
I'd probably fall out of my chair from shock. Most employers that I've had tend to stick with the version of software that they honed their skills on and were hellbent against upgrading at any cost. (Note: Most of my former employers developed on the LAMP stack, which doesn't help PHP's rep much I suppose)
Remaining backwards-compatibility and having good, reliable tests for your OWN software are two separate things and I am sure a special hell awaits those who are unfortunate enough to be using a few more unusual or legacy libraries. To be completely honest, I would expect no less from Java or python within the same major release, namely for the language and the interpreter to "just work" and understand my existing code but I would still be very worried about the functionality of my own software and all the libraries it comes with and that's what my own tests are for - but having these is no Perl-language-specific merit. Can you help me understand why Perl is so special or outstanding in that regard? Maybe just the very test-aware community?
I'd expect it too. Sadly my expectations are often not met :-)
Can you help me understand why Perl is so special or outstanding in that regard? Maybe just the very test-aware community?
I think it's a combination of the test-aware community - and the infrastructure that community has built up.
Little things like having the default behaviour of all the build/install tools be "run all the tests and only install if they all pass", rather than having running tests be optional.
Or take cpantesters.org for example.
For those who don't know cpantesters is basically a distributed continual-integration environment for all of CPAN. Any time anybody releases something to CPAN it gets downloaded and compiled on dozens of OS/perl combinations, and the automated tests run.
If I release a module on CPAN and it doesn't work on some obscure OS/perl combination I'll likely get an automated e-mail in a matter of hours. The results of those tests are public - so anybody can easily see what versions of what modules work on what platforms. You'll see them up right next to the module in all the CPAN search tools. So folk can easily understand where they'll be problems, and people with access to that platform can more easily find and patch problematic code.
So anybody who releases anything to CPAN gets a fantastic multi-platform CI tool for free.
And a discussion forum (http://cpanforum.com/). And a bug/issue tracker (https://rt.cpan.org). And a review platform (http://cpanratings.perl.org/). And automated "quality" metrics (http://cpants.charsbar.org/) and .... well... I could go on. All of them have public data or API routes so they very quickly get integrated into tools like https://metacpan.org and http://search.cpan.org/.
The perl community has done a stirling job taking the whole small-pieces-loosely-joined philosophy onto their community module distribution / testing infrastructure.
Because of the transparency and integration "bad" modules are obvious, and tend to get quickly fixed or deprecated. At the very least it's very easy to identify problematic areas and work around them.
This being said, this is not a snipe at how PHP or Python do it. It's a choice of the maintainers/developers.
Now, for me, Ruby has supplanted Perl in nearly every conceivable way -- OO Perl was always painful, and I do not miss ever having to bless a refrent again…
use Moose;
So, dear OP, good luck writing your large-scale multithreaded high-performance distributed applications using Perl.
And BTW, I do use Perl quite a bit and I really like it, for certain tasks. But I'd never make these kinds of comparisons.
Erm... He didn't? He said:
"While so much of the shiny-chasing buzz in the micro-ISV startup built-it-and-they-will-fund world seems to chase Clojure and Node.js and app-in-a-page tricks, Perl 5 continues to be my workhorse."
No comment on the reliability (or otherwise) of Clojure.
And much as I love Clojure - there's an element of truth there. Lots of folk using it because it's the new-and-shiny rather than it being necessarily the best solution. I know I've binned some Clojure stuff that would have been fun for me - because adding the JVM to the mix in production wouldn't have helped us actually get stuff done.
(and while it's an unfair comparison - since it's a vastly younger language - the transition to 1.3 wasn't fun for many folk :-)
How do you know what is in people's head? I assert that lots of folk are using perl because it's comfortable to them rather than it being the best solution.
So demands of a software project in the real world are very different than the academia. Although you can argue that Lisp is far more a better language than Perl, based on some parameters you wish to evaluate. Others might have totally different parameters, for example in terms of mere usability and pace of getting things done, Perl will fare better than Lisp.
While evaluating two technologies it is really important to define the parameters you wish to evaluate them upon. Without that we are just comparing Apples and Oranges and then arguing that nutrition on one isn't better than the other. Unless we define who needs an Apple and who needs an Orange for what reasons, we won't be able to say which is better than what for what purposes.
There fore comfort is really a subjective term. For a professor sitting in a university with endless time at his disposal Lisp will make the perfect and most comfortable language. But me sitting on P1 ticket assigned to me, and given 45 minutes to provide with solution has no other option but to use Perl. In other news I just have a weekend to hack up a automation or produce a quick prototype. You know what language I'm going to use, Its Perl.
Not because I hate Lisp or I'm uncomfortable. Its just there is no other option.
As somebody who loves both Lisp and Perl I'd probably say you'd be as productive (unless you were sitting in a domain that one language or the other was a better fit for). Well - apart from CPAN and the testing infrastructure. And the editor/IDE support is worse unless you're already an emacs person... but those are just coz Clojure is young.
I'm thoroughly sick of the Lisp == academic == hard myth. It's just nonsense. I've taught newbie devs Lisp and Perl in the past and both groups seem to take it on at about the same pace.
No,
And this is probably the reason why Lisp never took off post the appearance of C based languages. This is also why there are so many languages, because there are that many use cases for them. Denying the existence of a problem doesn't offer a solution. I can build anything quickly merely by using CPAN modules, I can manipulate strings and do all the text magic real quickly in Perl. That's not the same case with Lisp.
What you are saying is something like this. One guy wants reach from point A to B. He can either run or go in a car. You can argue that if he practices enough he can run as fast as the car, sure he can. But there is 0 logic in subjecting your legs to that kind of a torture, while all you need to learn is how to drive a car.
Now don't tell me that going from point A to B itself is wrong and he should be going to C instead.
You did read the very next sentence when I talked about my abandoning one Clojure solution for exactly this reason?
I love Clojure to death. It's excellent. But there are lots of folk like me who are just gasping to go play with production Lisp when other solutions would probably be better.
Not saying there aren't many great real-world uses for Clojure. Look at the stuff Datomic are doing for example... but I see lots of folk (myself included) spending two weeks tweaking Clojure stuff, dealing with warm-up timing issues for the JVM, etc. when we should probably just chuck something together with Sinatra and get the job done :-)
I assert that lots of folk are using perl because it's comfortable to them rather than it being the best solution.
Agreed. Sorry if I seemed to imply otherwise.
I have written all of what you describe: large-scale multithreaded high-performance distributed applications using Perl.
When necessary I have written perlXS bindings to C routines, but this is surprisingly infrequent. Most high performance system interfaces are exposed to Perl in an efficient manner. I've had Perl processes with tens of gigs memory resident. I have written non-blocking state machines in Perl which serviced (or served) over 100k connections in parallel. Which have run on over 100k machines at once. I have worked on huge modular, multi-team undertakings in Perl. The single caveat is that separate processes and explicitly shared memory is the parallelism tool of choice with Perl.
Luck wasn't a part of any of this. Perl will scale quite well, and if you think it doesn't you likely have a few things to learn about what the language/platform can do.
Your point about these comparisons being dubious (paraphrasing) is perfectly valid, by the way.
Nothing beats a mainframe for throughput & reliability and lots of the code is still COBOL.
IIRC SocGen has a vast amount of code written in some awful monstrosity of an internal language that nobody else has used for decades, but the cost of changing everything over to something more modern is so prohibitive that they just keep on accreting over the existing codebase.
Short answer: Yes :-)
Still the backbone of many banks, building societies, credit card companies, etc. See http://www.careerjet.co.uk/cobol-jobs.html for some of job adverts. This old 2009 article http://www.guardian.co.uk/technology/2009/apr/09/cobol-inter... is still pretty much true AFAIK.
Within hour drive from my house, I can tally at least a half-dozen corporate IT shops that outsourced heavily in this way, axing thousands (in aggregate) of jobs that normally were served by internal/domestic consulting houses.
Yes, on the backend there is still a lot of COBOL, even if it is running on micro-hardware as opposed to the old big iron. Claims adjudication, utility metering, charge card processing, billing for just about any corporation that existed pre-1980, etc.…
Yeah, they may not know the exact APIs you're using, but that's usually the case anyhow.
What doesn't work so well, or at least takes a lot longer, is to take somebody with only Java, C/C++, or other such languages, and throw them in.
In fact I use to visualize that each programmer worshipped the specific animal that shown on the O'Reilly book cover: And I'm still haunted in my dreams by that camel. Of course the best programmers in my experience like to work in multiple languages -- but again there aren't that many of them...
* This was a few years ago so this was a reference to PHP and Cold Fusion which tended to get mashed into HTML. Python was around then, but a very new thing -- and this was before the age of Ruby on Rails.
All of the other languages I mentioned are roughly as OO as Perl. (You sometimes have to go looking for it, and Perl's probably ultimately the weakest at the core, but it's still there and mostly strong enough it doesn't matter.)
Most Java programmers can't write simple apps without the help of an IDE. Or refactor a small part of a large project with an Text editor. In many other languages forcing people to write programers in a particular style often leads to code written by bad and good programmer look the very same.
I'm curious why you think editor choice is the sign of a good developer?
Pretty much nobody I know can code with a line editor (anybody else out there remember ed?) - that doesn't make them worse developers.
Hell - I'd jump at an IDE that let me do automated refactoring in Perl. I like getting the computer to do things for me. Laziness is a Perl value :-)
I have nothing against IDEs. But anybody who claims to know a language must at least able to work with the source code and semantics.
If a person absolutely can't code at all. I mean slowly is still acceptable. But if he absolutely just can't write code without an IDE, I would doubt his claims of knowing the language.
Knowledge of tools != Knowledge of a programming language.
Would you be productive in QED http://en.wikipedia.org/wiki/QED_(text_editor) ? Should I doubt your coding skills because of that?
Knowledge of tools != Knowledge of a programming language.
Agreed. But you seem to be saying that people who code well with an IDE, and can't code well with a more vanilla text editor, means that they don't know the language. This is a tool knowledge issue - not a language knowledge issue.
Some people are good at coding, and others are bad at coding. IDE/editor choice has little to do with it. Lines like "Most Java programmers can't write simple apps without the help of an IDE" are just false - and have nothing to do with whether the developer is any good or not.
Twenty years ago people were saying the same thing about lazy developers who use screen based editors instead of line based ones. I'm sure that twenty years before that folk were complaining about folk who use terminals instead of punched cards as god intended :-)
method foo ($a, $b) {
$self->blargh($a + $b);
}The same argument applies for every new symbol imported into a namespace.
Example 1 (my work's internal source filter format):
sub function1( CODE $code, ARRAY $arr )
{
# body
}
Example 2 (standard Perl): sub function1 {
my ($code, $arr) = @_;
die "Bad params." unless ref($code) eq "CODE"
and ref($arr) eq "ARRAY";
# body
}
Example 3 (Method::Signature): func function1 (Code $code, Array $arr)
{
# body
}When not using perl5i or playing with MooseX::Declare I will usually default to Params::Validate so your example would look like this:
sub function1 {
my ($code, $arr) = validate_pos( @_, {type => CODEREF}, {type => ARRAYREF} );
...
}1) I've often seen people shift from @_ half way in the middle of a function. If you really want to be certain about a method's formal parameters you have to read the entire function.
2) Also @_ is used in other circumstances which can cause mass confusion. For example Try::Tiny uses @_. It is difficult to guess if you getting a formal parameter or something else entirely (I"m not a fan of magic variables in case you can't tell). If you're Chromatic you might be able to know the probably hundred of uses of @_, but for a normal programmer you're screwed.
3) What if you want to use named parameters? You essentially have make a pointer to a hash, populate it, and unreference it. my $p = {'name' => 'val1', 'name2' => 'val2' }; f($p); sub f { my $name = $_[0]->{'name'}; my $name2 = $_[1]->{'name2'}; }
In other languages like python you can just do something like: def f(name, name2): ...
f(name = 'val', name2 = 'val2')
I've never seen a language handle function parameters as poorly as Perl. I forget almost all the Ruby I once knew but I'm pretty sure it is handled in a reasonable way similar to Python.
Also, sometimes you just want to work on an arbitrary list of items. If you process one item and then shift it, that's a reasonable thing to do.
2. If you adopted the convention in 1, this shouldn't bite you. (I've never actually encountered this issue myself...)
3. You are misinformed. You can easily do something along the lines of:
f({a => 'foo', b => 'bar'});
sub f{ my ($args) = @_; say $args->{a}; }
There's probably a module of CPAN to do this even nicer.some_func(\%$some_object, \%some_hash);
and used variables like $a and $b as mainline code parameters...
However, if having dangerous features were something to hold against a language in general, nobody would be using C (maybe Linux in such an alternate universe would be written in Fortran or some other abomination). On the whole, I think that well-written Perl is very good. Poorly written Perl is... well, poorly written.
do_stuff(Foo => 1, Bar => $baz);
sub do_stuff {
my %args = @_;
my $foo = $args{Foo};
# etc...
}Combine its shorthand and with the fact that it's already getting hard to find Perl people, and we could see some dedicated Perl warriors doing very, very well in the coming years.
I can, of course, understand why you would really want it to be dead ;-)
Perhaps there still are a few corners where there are some rotting corpses hacking away on AS/400s which are actually gluing everything together!
I remember getting to sledgehammer the crap out of our AS/400 platforms and incinerate two entire pallets of IBM manuals - was "a great day for freedom" to paraphrase Pink Floyd.
My last job was programming a snazzy Perl system. My current job is at a startup that my last boss helped found. He chose Ruby because he was tired of trying to hire for Perl programmers. After being involved with the hiring process over there as well, I'm inclined to sympathize. Honestly, we ended up just mostly advertising for programmers with experience in Ruby/Python/etc who would be willing to do Perl.
That's the only insurmountable-mountain I know of.
(Postscript. If you're the rare actual-really-good Perl programmer looking for a job, I am aware of two places willing to hire you, one in Sunnyvale and one in NYC. PPS. Sorry, probably no telecommute. But I don't work there these days so I'm not sure.)
By contrast, I assume you can say something like "Object-oriented software engineer (Python)" or "Object-oriented software engineer (Ruby)" (or Frontend Engineer / Backend Engineer / etc) and not have this particular set of problems. I don't know what problems you would have, but... not those.
Now, to be fair, it worked marginally better when the company-recruiters weren't all jerks about letting us post a programming challenge with the posting (because it didn't fit in with a preexisting workflow)... which makes it easier to find the random Spanish major with decent programming instincts and a little Perl. But still.
Most of the great Perl programmers I know either have full-time jobs or have little desire to relocate. (I'd entertain interesting short-term telecommute gigs now and then myself.)
Honestly not trying to start a religious war here - just curious - and I think it's fair to compare the two languages as they are both runtime interpreted and have relatively similar characteristics (and obviously Ruby took a good dose of inspiration from Perl, anyway).
http://www.lucas-nussbaum.net/blog/?p=617 http://www.lucas-nussbaum.net/blog/?p=681 http://news.ycombinator.com/item?id=2059964
Much of Perl's use is by sysadmins, which means it plays well in their space. By contrast, much of Ruby's use is by web developers, many of them on bastardized MacOS systems (they're born bastards, it's not the developers' fault ;-). Which means that Ruby's packaging is whack.
I don't hack much of either, though work around both. The nice thing about Perl from my perspective is:
1. It's included with the system. I run Debian/Ubuntu boxes if I can possibly help it, Perl is of of the tools used to write a whole slew of system scripts, and as a consequence, it's very well managed within the distro. Red Hat/CentOS aren't far behind.
2. CPAN plays nice. Under Debian, your CPAN bundles are installed to /usr/local/ Debian's just sorting out where to store Ruby gems.
Thanks to chromatic for mentioning perlbrew. I've encountered RVM in the past month or so and have been trying to wrap my head around it. Understanding RVM in terms of perlbrew helps a lot: http://ithaca.arpinum.org/2010/06/13/rvm-and-perlbrew.html
* I've had more years of Perl than I have of Ruby. While there's not a massive difference it comes a bit easier to my fingers and brain.
* The testing framework is better - it's much easier to integrate different styles of testing and integrate tests running in other languages
* I can usually get more people to do my work for me with CPAN than I can with rubygems
* Moose has some interestingly different ways of breaking up abstractions (Moose is the de facto way of doing OO in Perl now. Moose is to Perl as CLOS is to Lisp)
You're probably not going to be suddenly more productive if you switched to Perl - but there are some plus points. As does Ruby of course.
Swings or roundabouts. Your choice :-)
That's exactly what I'm doing. Reliability is only one reason I chose Perl over Ruby, but upgrading three real-world applications my business relies with their dependencies on to a new major release of Perl 5 in an afternoon while doing other things and only having to intervene three times is a tremendous boon.
Upgrading from Ruby 1.9.2 to 1.9.3 wasn't that easy.
DBIx::Class, Moose, Catalyst, Template Toolkit - these are a joy to work with. People seem to be just ok that they have Rails, bitch about Active Record, and honestly, just don't seem to love their tools.
TAP-based testing is awesome sauce. Ruby gets this so wrong with all tools checking return values of scripts + the occasional hacked together jUnit outputter. Even the testing tools stolen from Ruby (like Test::BDD::Cucumber (which I may have written)) use TAP and Perl's testing tools all the way down.
Finally: there's CPAN. It Just Works. I started off a Perl dev, and use of any other language's package system has just made me sad face.
(and I'm saying this as somebody who love's Perl - I'm not seeing the connection)
Maybe I need to know Ruby or Python? :D
Thanks.
http://www.net-a-porter.com/ http://www.lovefilm.com/ http://www.photobox.co.uk/ http://www.booking.com/
Send me a CV and I can make sure it gets to the right people.
I also hear Blekko is all Perl (it's the dmoz directory-people making a search engine. it's got social-search-related features, too, or something like that.) Apparently they have some fancy sophisticated technology for their backend systems (store big bitfield indexes on SSDs with a disk-backed store for the rest, spread across dozens of nodes, etc.) But I don't know anyone actually working there.
If you have the initiative you can look up their job applications yourself :P
(I've been using their perl/mason based ticketing system, RT, for 5 years)
http://www.grantstreet.com/
http://www.rentrak.com/
The first one is full remote, and I hear they have awesome benefits packages. I had two co-workers go there. I'm not sure if they hire outside of the US though.Inside any function $_ will refer to the argument of the function, so you could program without ever using named parameters like in Perl 5. A parameters list like ($x,$y,$z) will just create new place forms rather then variables. I think this would make for a pretty interesting programming language semantics. On the other hand, I don't see much use for the @ and % sigils because I just consider lists to be structures with numeric places and maps to be structures with general places, so I actually prefer PHP style sigils.
No, it shouldnt. But it's a proxy measure for the engineering and productisation effort which goes in.
It's relatively easy to get features in quickly with breakage. It's easy to have stability with no change.
It's relatively hard to continuously improve with good reliability and back-compat. Perl was a major leader for automated testing since before TDD was a buzzword.
Modern perl is a cool language with a great OO model and a shitty threading system (seriously, use multiproc if you want concurrency or just go async with one of the eventing systems).
It has some serious warts (no implicit deref of references, the scalar/list context is arguably more trouble that it's worth) and suffers from an image problem.
But it's a bulletproof, fast, widely deployed, portable, actively improving scripting language which doesn't have a lot of the warts of it's competitors (broken lexical scoping, problematic object model, poor performance etc). Oh "and CPAN" (ObMention)
It's not that the the ability to upgrade the interpreter, and several hundred dependencies, and have several tens of thousands of lines of production work easily is good (although it would be tough to argue that it's bad :-)
It's what being able to do that successfully says about the reliability of the perl ecosystem as a whole.
The investment the perl community has made over the last ten years in building the best testing infrastructure of any language (seriously - it's damn excellent), and fostering a community that's values stuff working has paid off in spades.
My experiences match chromatic's in that it just fracking works.
The OP seems to think it's a good idea to upgrade his production code to the newest stable interpreter just because it was released. This is a recipe for disaster. Sometimes there are just hidden bugs you don't see until a weird use case blows up your code, and thorough stress testing should be performed after the unit testing to ensure no major surprises after upgrade.
The best rule for keeping your software stable is: don't change anything.
There's a tradeoff here that you're glossing over. Given that each newer version is presumably some amount better than the previous one, eventually the benefits of upgrading will outweigh the costs, at least if you're going to continue making changes to your software.
I don't think chromatic was saying "everyone should immediately upgrade to the latest version of Perl". I think he was saying "upgrading to the latest version of Perl isn't as scary/costly as some people think; I did it, and here's my experience."
Also, keep in mind that sometimes there are hidden bugs in the old version, too. My employer just ran into a problem with the de-allocation of deeply nested structures being implemented inefficiently in Perl 5.8 (which has been in production for close to a decade); the bug was fixed in 5.14.
You're putting words in my mouth and knocking down the resulting strawman. I upgraded for Unicode and performance improvements.
[1] http://blogs.msdn.com/b/oldnewthing/archive/2007/08/16/44070...
Ruby ~40 Python ~40 Java ~50 Perl ~1800
Perl can have all the community support, packages, and testing that it wants, but I dislike programming in it and find it difficult to code in. This is not because I have only ever done Ruby or Javascript, I would consider my strongest languages to be Objective-C and Java, I have used C quite a lot, I know what I am doing with programming languages. I just dislike Perl.
Did you know there is a Perl package that will catch references to undefined symbols and fuzzy match them to the closest it can find in the current scope. To me, that seems to be the marker for the general quality of the code.
* ~ 35, Python
* ~ 53, Java
* ~ 59, Ruby
* ~189, Bash
* ~253, Perl <=====
* ~928, PHP
Perl has a higher keyword count than Ruby or Python, but remember Perl's keyword list includes its core socket/network library (which Ruby/Python/Java don't contain in theirs...according to Notepad++).OP is clearly thinking of PHP.
It's a language design choice too - Perl very deliberately has different keywords for different data types. So we have "+" for numbers and "." for strings. ">" for numbers, "gt" for strings - and so on. The argument being that what you spend in having to remember multiple keywords you gain back in increased code clarity.
And it is being mooted that these will be moved out into core modules at some point (ref: http://lwn.net/Articles/458714/).
To me, that seems to be the marker for the general quality of the code.
There's also a module which allows you to program in Latin. Does that mean that every Perl programmer eventually has to live in Europe?
To me, just the fact that this is possible witnesses about the flexibility of the language.
Edit: I'd guess the troll's main account votes the troll posts up... maybe a heuristic can be made for the HN algorithm?
It's not that I think perl will be significantly (or at all) nicer, but I think the readability difference is often overstated and I'd like to test that thought.
def Factorial(x):
output = 1
for i in xrange(x):
output *= (i + 1)
return output
def Factorial2(x):
return reduce(operator.mul, xrange(1, x + 1), 1)
I provided two versions, both with constant memory, to show how it'd look with explicit iteration and without it.With this, I get:
>>> Factorial(200)
788657867364790503552363213932185062295135977687173263294742533244359449963403342920304284011984623904177212138919638830257642790242637105061926624952829931113462857270763317237396988943922445621451664240254033291864131227428294853277524242407573903240321257405579568660226031904170324062351700858796178922222789623703897374720000000000000000000000000000000000000000000000000L
Exponentiation: def Power(a, b):
if not b:
return 1
if b % 2:
return Power(a, b - 1) * a
x = Power(a, b/2)
return x * x
Add a constant: lambda x: x + 7
Or, if you want to name it globally: def TweakValue(x):
return x + 7
How do they look in Perl?First one (not 100% sure it's constant memory, I think perl optimises the for to avoid instantiating the (1..$n) list:
#!/usr/bin/perl
use Modern::Perl;
use bigint;
say fact(5000);
sub fact {
my ($n) = @_;
my $output = 1;
for my $i (1..$n) {
$output *= $i;
}
return $output;
}
(Took the value up to 5000 to get something which ran long enough to get a measurement, on my laptop it runs (including startup time) in ~1.2s. (Can we compare runtime too? I know we're discussing readability, but I'm interested).The reduce version (again, I'm unsure of const mem req). Comes in at ~1.4s:
#!/usr/bin/perl
use Modern::Perl;
use List::Util qw(reduce);
use bigint;
say fact(5000);
sub fact {
my ($n) = @_;
return reduce(sub { $a * $b; }, 1, (1..$n));
}
The add a constant (true lambda, closing over lexicals in scope, etc etc) is 'sub': sub { my ($x) = @_; $x + 7; }
(doesn't have the python lambda limitations). (Be aware that perl GC is refcounted though, so ref cycles are possible).Edit: I think the languages are comparable in terms of features and also readability. People may dislike leading sigils and that's fair, but I dislike python's "no need to declare your vars, just hope you don't typo an assignment" approach to lexicals.
For example:
return reduce(sub { $a * $b; }, 1, (1..$n));
would be: reduce { $a * $b } 1..$n;
This my $output = 1;
for my $i (1..$n) {
$output *= $i;
}
would be: $output *= $_ for (1..$n)
So, I have a question for you(assuming you write perl for a living). Is this your preferred style, or you do this to appease readability police which demands programming languages be readable by non programmers? Because really, what kind of programmer programs in perl and is averse to $_? $output *= $_ for (1..$n)
and you're right to call me on it. If I am writing a multi-line for loop, I do like to name the loop var though.I think this is an interesting point (in a discussion about readability), do non-perl coders think the one-liner (with 'for' suffix) is more or less readable?
(I also prefer explicit return for maintenance reasons, except possibly in one-line subs)
It does since 5.005 - so for a good long time now :-)
The reduce version (again, I'm unsure of const mem req). Comes in at ~1.4s:
This would allocate the array I'm afraid. You'd could use something liek List::Gen's reduce() to get around that.
def function(x, y, z):
versus
sub function { my ($x, $y, $x) = @_; }
The overhead is only really the 'my = @_;' chars, but it is annoying. On the other hand, it does allow you to do things like partially unpack args and pass the rest as a bundle to a super class.
def method(self, *args):
a, b = args[:2]
super(self).method(*args[:2])
Perl's lack of using the definition for the variables doesn't necessarily make it 'more powerful.'And with @_, you're free to use positional arguments, named arguments, variable arity, etc. without penalty. Some languages only give you some of that.
use Method::Signatures::Simple;
http://search.cpan.org/~rhesa/Method-Signatures-Simple-1.02/...But you might instead want to look at this (or similar with Moose support) to get simple type declarations:
http://search.cpan.org/~barefoot/Method-Signatures-20120523/...
use bignum;
use v5.10;
=cut
def Factorial(x):
output = 1
for i in xrange(x):
output *= (i + 1)
return output
=cut
# Direct translation
sub factorial {
my $x = shift;
my $output = 1;
for my $i (1 .. $x) {
$output *= $i;
}
return $output;
}
say factorial(200);
=cut
def Factorial2(x):
return reduce(operator.mul, xrange(1, x + 1), 1)
=cut
use List::Util "reduce";
sub factorial2 {
my $x = shift;
reduce { $a * $b } (1 .. $x);
}
say factorial(200);
=cut
def Power(a, b):
if not b:
return 1
if b % 2:
return Power(a, b - 1) * a
x = Power(a, b/2)
return x * x
=cut
sub power {
my $a = shift;
my $b = shift // return 1;
if ($b % 2) {
return power($a, $b - 1) * $a
}
my $x = power($a, $b/2);
return $x * $x;
}
# lambda x: x + 7
my $plus7 = sub { $_[0] + 7 };
# Or:
my $plus7 = sub { my $x = shift; $x + 7 };
say $plus7->(14);
=cut
def TweakValue(x):
return x + 7
=cut
sub plus7 { $_[0] + 7 }
say plus7(14); sub factorial($n) {
my $output = 1;
for 1..$n -> $i {
$output *= $i;
}
$output;
}
or sub factorial2($n) {
[*] 1..$n;
}
Pretty anonymous function to add a constant: -> $x { $x + 7 }
Really short version: * + 7
Named: sub plus7($x) {
$x + 7;
}Umm, did you mean:
def factorial(x):
output = 1
for i in xrange(2, x):
output *= i
return output
Here are the perl versions. Such trivial examples are going to look the same in languages which share the same paradigms. use List::Util qw(reduce);
# This is how I would write it.
sub fact1 {
my $num = shift;
my $output = 1;
$output *= $_ for (2 .. $num);
return $output;
}
# Most people don't prefer inline loops and $_ variable, though
# I don't see why not.
sub fact2 {
my $num = shift;
my $output = 1;
for my $i (2 .. $num) {
$output *= $i;
}
return $output;
}
sub fact3 {
my $num = shift;
return reduce { $a * $b } 2..$num
}Yes. That makes my Python example incorrect(should be xrange(2, num + 1))
> 1..^$x in Perl 6, don't recall if that's the Perl 5 syntax or not.
Perl 5 doesn have 1..^$x. I have always used 1..($n - 1) where I needed it - don't know if there is a better alternative.
Or just xrange(num) and then, as in my original code, output *= num + 1. :-)
HN ate your asterisk(it uses asterisk to mark italics), or something wrong with my chrome app for HN. In your post, I saw:
def Factorial(x): output = 1 for i in xrange(x): output = (i + 1) return outputEnglish does look simpler than French, too. On the other hand, once you get beyond the accents, you know how to pronounce French, whereas that's not the case with English (cf. "ghoti"). Personally, I never was that bothered by e.g. the type characters, and quite often they were quite helpful about the context expected/required. But then again, I'm German, so maybe growing up with a somewhat ridiculous grammar and Funky Capitalization helped (there's a Perl module that allows you to write code in Latin, and here the cases and other grammatical structures replace the funky characters).
Perl certainly has its weaknesses. Some operations should probably be bound to types/objects instead of C-like functions, references are often difficult to untangle and the default object system ain't that grand (on the other hand: Moose). But I've yet to find a language that doesn't have similar weaknesses. Due to the somewhat funky syntax, they're just quite obvious. What does that dollar sign right there indicate? On what default variable is this code operating? Schwartzian what? But I would call that "traceability" issues. And this certainly also happens with macros, meta-programming, complicated object hierarchies, generators, decorators, DoI containers, etc.
It probably does matter for casual programmers, i.e. people who don't work 20+ hours/week in Perl. Sysadmins come to mind. But if your involvement with the language is beyond that, I think "readability" is quite often a matter of taste, not more. Which, of course, doesn't totally disqualify this argument. It's just more a matter of rap vs. punk, not junk food vs. rucola salad.
Although I'm not sure whether describing Perl as the Vietnamese of programming languages would be a good selling point, so I'll stick with French ;)
And the number 3 is different from your fingers being number now than they were before.
Not sure about 'familiar' though.
Perl is my set of power tools that sit in my basement for weeks until I get them out and fix/make/do something. And what the OP said is correct. I can install new versions and run 10 year old code without issues.
These days all the cool languages have funny syntax (hell, Ruby lifted most of perl's weirdness directly), sometimes (as with coffeescript) it's touted as a feature. So go back and look at perl with modern eyes. I think you'll find most of the conventional wisdom about its readability was more about the conventions than the wisdom.
Readability and reasonable shoot-self-in-foot protection are not optional. See the article from earlier today about not catering to power users. Same concept. You can't really design a language for the top 5% of programmers and expect it to gain any sort of acceptance. (See: Haskell, Ocaml)
Perl is a power tool. The reason it can be unreadable is because of it's terse syntax, wherein resides its power. If you value readability above power then you choose Java, and I would agree that for a large enterprise app developed by an army of mediocre developers then Java is surely the better choice. However to judge the absolute merits of a language like Perl on reputed readability, without taking into consideration what its terseness allows, and how it works for large scale development given a sane coding standard is just burying your head in the sand.
You will be shocked how few tools are there for the other kind of data.
Basically - it's a balance - don't be too dumb, but don't be too clever either. I'd submit Python as being solidly in the middle ground here.
Your average PHP web dev is not the cutoff for the 95th percentile. But yes, I can imagine them trying to understand monads. I have also observed them succeeding at understanding monads. They aren't hard to learn, just something you need to learn. Being able to learn simple things doesn't make you the top 5%.
MongoDB (if that's what you are using?) has a few more dependancies however it actually uses Any::Moose and so could you Mouse instead of Moose: http://deps.cpantesters.org/?module=MongoDB&perl=5.16.0&...
Were you using cpanminus to install your modules? Because its much faster than default cpan command.
I just tested using cpanminus (cpanm) on a vanilla perl install and installing Moose & MongoDB modules took 4 minutes here.
Here's a summary:
Install perl-5.16.0 via perlbrew - under 15 mins
Install cpanminus - 5 secs
cpanm Moose - 2 mins 5 secs (installed 22 distros)
cpanm MongoDB - 1 min 52 secs (installed another 20 distros)
Here's the log: https://gist.github.com/2836306