Actually the DarkPAN might matter a lot

jarich on 2009-07-05T04:57:56

I agree with chromatic that it would be really nice to get a whole bunch of "Modern" features turned on in later versions of Perl by default. However, I also accept that this is probably a bad idea.

I run a Perl training business. It would make me overjoyed to not have to remind the students to add use strict; use warnings; use autodie; to the top of each script. The students aren't being lazy or difficult when they forget to add these things, they're just forgetful because I'm teaching them so many things all at once.

On the other hand, I do consulting too. There are many, many Perl systems out there in the real world; systems which must work for the business to function; but which are not well written. Systems without test suites. Systems without even version control. Systems without development or testing environments (yes, everything is done in production). It's terrifying. Not just to me, but also to their developers, so these system are left alone, and only touched if absolutely necessary. This is the DarkPAN.

Many of the owners of these systems are already afraid to upgrade, so they don't. Whether they're still using Perl 5.5.3 or 5.6.1, it's "good enough". But these are not the people we're worried about.

The ones we need to worry about are the ones with active Perl developers who are pushing and pushing for a newer version of Perl, so they can use new features in their new projects (without thought for existing systems). If Perl is backwards compatible, then most of the time they should be able to get those new features and the monolith that no one wants to touch should still work. I've seen an organisation jump from 5.5.3 to 5.8.8 and there was about 4 hours work for one developer needed to fix things (mostly related to changes in some module APIs, I don't remember which). This was considered a good bargain.

I don't think it's reasonable to make the 5.10 branch the last upgrade that such organisations can reach without having to massively edit their scary monoliths. I don't think they should have such scary monoliths, but that's another story. As such, I would be unhappy if all the new modern stuff I want in Perl was turned on by default. People should be able to write Perl 5.5.3-like code and have it work in Perl 5.10. To illustrate this, consider the following code:

#!/usr/bin/perl
# Very bad code!

open FILE, "test2.pl";

while() {
        print;
}

Under Perl 5.5.3 through to 5.10 (and probably earlier versions as well), that prints out the contents of "test2.pl" if the file could be opened, and doesn't print out anything otherwise. This is presumably the desired behaviour. Moving this code to a version of Perl that turns on strict, warnings and autodie automatically would require this snippet of code to be completely rewritten or to have warnings and autodie manually turned off:

#!/usr/bin/modernperl
# Very bad code!

no autodie;
no warnings;

open FILE, "test2.pl";

while() {
        print;
}

Of course, that these things need to be turned off should itself be a warning that the code is badly written, but strangely enough badly written code does exist. The next obvious way to achieve the same effect is with file test operators.

#!/usr/bin/modernperl
# Only slightly better code

# Hope we don't get a race condition
if(-r "test2.pl") {

        open my $fh, "<", "test2.pl";
        while(<$fh>) {
                print;
        }
}

Fortunately, we seem to already have a good solution to the modern Perl problem. Perl 5.10 had the right idea with use feature qw(...); and Perl 6 has the right idea with use v6;. As others have suggested, we should be able to make most people happy with a pragma that does the right thing. So instead of starting every program with chromatic's boilerplate:

use 5.010;

use strict;
use warnings;

use utf8;
use Carp;
use Want;
use CLASS;
use SUPER;
use autodie;
use autobox;
use signatures;

use mro 'c3';

use IO::Handle;
use File::stat;
use autobox::Core;
use UNIVERSAL::ref;

Perhaps as of 5.12 we can just say:

use 5.012;

To turn on all the appropriate modules and features. Failing to specify such a version means we're in classic mode, and we provide the same interface as we did before. This has the logical advantage that scripts written for 5.12 are clearly marked, so that someone with Perl 5.8 knows that there may be features in use that aren't available to them.

This shouldn't be problematic, because we're already doing this magic when we write use 5.010.

It should be noted that this means that specifying the version stops meaning the minimum version of Perl we want to use and instead becomes an instruction about exactly what we're expecting to get. So whereas anything which says use 5.010 should work with Perl 5.12 and 5.14; it is also saying that it does not want to inherit any new and shiny defaults from either of those versions.


Less Boilerplate versus No Boilerplate

chromatic on 2009-07-05T05:55:45

I'd like to see all new features enabled by default, but I can accept as a compromise the alternative of the meaning of use VERSION changing the way you describe. That's a decent balance between forward compatibility and modern behavior.

Thank you

phaylon on 2009-07-06T11:26:11

and ++ for that well written explanation. I fully agree with your points.

I'm sorry to disagree

btilly on 2009-07-07T06:33:15

Seriously, you did a very good job of putting forth your point of view, and I wish I could simply agree with it. But I can't. Saying that when you ask for a particular version of Perl, you won't get new features, forces anyone implementing new features to have to put a check in their code to detect whether to go with the new or the old version of the feature. This would force the internals to get even more messy than they already are, because you're now maintaining a promise for perfect backwards compatibility. (Rather than just good enough to satisfy tchrist, merlyn, etc.)

I personally have enough comfort with the judgment calls that are made on backwards compatibility supplied by Perl 5 to continue letting pumpkings decide whether it is better to just give everyone a new feature, or give people the ability to control whether they will see it. Which means that I don't want anyone to be promised that they will only get new features if they specifically ask for them.

Re:I'm sorry to disagree

jarich on 2009-07-08T02:31:17

You make a good point. I think "good enough" backwards compatibility would still work fine though. My main concern is the addition of new pragmas that might be added to be loaded on default.

When I write use 5.010; I want to get given, when, say, and all the rest. But I don't expect autodie, strict, warnings and other such things to be turned on for me automatically. That could seriously break my code. I really like autodie, but I have some legacy code that does its own error handling. autodie does not allow for such code, unless you turn off autodie, it'll trump your error handling with its own. chromatic and others are arguing that these pragmas should come on by default in some future version of Perl. Which is an idea I also feel has much merit.

I'm merely suggesting that perhaps we can use the version number as a signal as to which of these pragmas should be loaded. I think these are much more likely to cause problems for the monoliths than new operators and similar features.

Re: I'm sorry to disagree

Maddingue on 2009-09-23T10:03:30

Jarich, thank you very much for expressing so clearly what it also my point. Yes, we may be "backward compatibility nazis" like some people are saying, but those people should know that for most companies out there, Perl is just like AWK, except more powerful. You expect it to always works the same way you expect the Sun to raise each morning.

Also, to illustrate what Jarich said, here is a ~250 lines module which is perfectly valid and working Perl code:

$ perl -c BigBrother.pm
BigBrother.pm syntax OK

Now, let's say that strict is enabled by default:

$ perl -Mstrict -c BigBrother.pm
Global symbol "$DEBUG" requires explicit package name at BigBrother.pm line 33.
Global symbol "$script" requires explicit package name at BigBrother.pm line 40.
Global symbol "$BBHOME" requires explicit package name at BigBrother.pm line 49.
Global symbol "$line" requires explicit package name at BigBrother.pm line 53.
[ cut 88 lines or errors ]
Global symbol "$hosts" requires explicit package name at BigBrother.pm line 129.
Global symbol "%host" requires explicit package name at BigBrother.pm line 129.
BEGIN not safe after errors--compilation aborted at BigBrother.pm line 130.

Oops! You just broke the monitoring system of more machines than you ever met in your whole life.

No java-like startup times, please

srezic on 2009-07-08T09:55:32

I tried out chromatic's boilerplate (with 5.8.9, as my 5.10.0 does not have all modules installed, and without m3): /usr/perl5.8.9@RC2/bin/perl /tmp/chro.pl 0,31s user 0,02s system 65% cpu 0,503 total

Ouch. The empty perl programm took almost no time: /usr/perl5.8.9@RC2/bin/perl -e 1 0,00s user 0,00s system 38% cpu 0,007 total

So if this should really go into perl some day, it has to be much more efficient.