Make the Pragmas Stop!

I've been following the development of a few things in the Perl community lately, and it’s leaving me very frustrated. For years now, I've written modules that start with the same incantation:

package My::Module;

use strict;
our $VERSION = '0.01';

Pretty simple: declare the module name and version, and turn on strictures to make sure I'm not doing anything stupid. More recently I've added use warnings; as a best practice. And even more recently, I've started adding use utf8;, too, because I like to write my code in UTF-8. And I like to turn on all of the Perl 5.10 features. It’s mildly annoying to have the same incantation at the start of every module, but I could deal with it:

package My::Module;

use strict;
use warnings;
use feature ':5.10';
use utf8;

our $VERSION = '0.01';

Until now that is. Last year, chromatic started something with his Modern::Perl module. It was a decent idea for newbies to help them get started with Perl by having to have only one declaration at the tops of their modules:

package My::Module;

use Modern::Perl;
our $VERSION = '0.01';

Alas, it wasn’t really designed for me, but for more casual users of Perl, so that they don’t have to think about the pragmas they need to use. The fact that it doesn’t include the utf8 pragma also made it a non-starter for me. Or did it? Someone recently suggested that the utf8 pragma has problems (I can’t find the Perl Monks thread at the moment). Others report that the encoding pragma has issues, too. So what’s the right thing to do with regard to assuming everything is UTF8 in my program and its inputs (unless I say otherwise)? I'm not at all sure.

Not only that, but Modern::Perl has lead to an explosion of other pragma-like modules on CPAN that promise best pragma practices. There’s common::sense, which loads utf8 but only some of of the features of strict, warnings, and feature. uni::perl looks almost exactly the same. There’s also Damian Conway’s Toolkit, which allows you to write your own pragma-like loader module. There’s even Acme::Very::Modern::Perl, which is meant to be a joke, but is it really?

If I want to simplify the incantation at the top of every file, what do I use?

And now it’s getting worse. In addition to feature, Perl 5.11 introduces the legacy pragma, which allows one to get back behaviors from older Perls. For example, to get back the old Unicode semantics, you'd use legacy 'unicode8bit';. I mean, WTF?

I've had it. Please make the pragma explosion stop! Make it so that the best practices known at the time of the release of any given version of Perl can automatically imported if I just write:

package My::Module '0.01';
use 5.12;

That’s it. Nothing more. Whatever has been deemed the best practice at the time 5.12 is released will simply be used. If the best practices change in 5.14, I can switch to use 5.14; and get them, or just leave it at use 5.12 and keep what was the best practices in 5.12 (yay future-proofing!).

What should the best practices be? My list would include:

  • strict
  • warnings
  • features — all of them
  • UTF-8 — all input and output to the scope, as well as the source code

Maybe you disagree with that list. Maybe I'd disagree with what Perl 5 Porters settles on. But then you can I can read what’s included and just add or removed pragmas as necessary. But surely there’s a core list of likely candidates that should be included the vast majority of the time, including for all novices.

In personal communication, chromatic tells me, with regard to Modern::Perl, “Experienced Perl programmers know the right incantations to get the behavior they want. Novices don’t, and I think we can provide them much better defaults without several lines of incantations.” I'm fine with the second assertion, but disagree with the first. I've been hacking Perl for almost 15 years, and I no longer have any fucking idea what incantation is best to use in my modules. Do help the novices, and make the power tools available to experienced hackers, but please make life easier for the experienced hackers, too.

I think that declaring the semantics of a particular version of Perl is where the Perl 5 Porters are headed. I just hope that includes handling all of the likely pragmas too, so that I don’t have to.

Backtalk

Quinn Weaver wrote:

Spot-on. This is one of the two Perl areas where There's More Than Too Many Ways to Do It. (The other, of course, if object-orientation.)

Jakub Narębski wrote:

There is also perl5i

In addition to Modern::Perl there is similar perl5i (imaginary Perl 5, IIRC).

Steffen Mueller wrote:

What you want is:

package Name '0.01'; use 5.012; use utf8; use warnings;

"use 5.012" will automatically do two things other than checking the version: a) use strict; (this cost me a lot of hair and quite a bit of discussion to get in) b) use feature ':5.12'.

It can't 'use warnings', too. We were going to include it bit even disregarding the vehement opposition of people who fear their logs would fill their disks, it was a language design decision from Rafael because it may, in some cases, have produce strange action at a distance. I don't remember the details, but I do remember I came around to his line of thought eventually.

--Steffen

Sylvain Côte wrote:

Wouldn't something like this:

use 5.012 ; 
use 5.012 qw(utf8 warnings) ;

be cool?

chromatic wrote:

chromatic's status on Thursday, 17-Dec-09 00:45:03 UTC

Make the Pragmas Stop! http://www.justatheory.com/computers/programming/perl/make-the-pragmas-stop.html !perl

Sean Burke wrote:

I hesitate to suggest this, but: how about leaving "package" behind as a still-accessible internalism (what was the last time you said "I'm working on a Perl package"... and where "package" didn't mean a package like an apt package?), and instead have:

module Whatever 0.01;

and maybe

class Whatever 0.01;

(Whether there's any difference between the two, I have no idea.)

I'm tempted to allow a flourish of possibilities before the ";" there, but every clever possibility that I think of, is very spazzy for some reason or other.

Wait, hey, I know! Since everyone loves/wuvs "~~" now, how about this?

module Whatever 0.01 ~~ 5.10.3;

Bam!

I WOULD LIKE TO THANK THE ACADEMY...

chromatic wrote:

You Can't Add Keywords to Perl 5

I like the idea, Sean, but it'll never work as long as it's impossible to add keywords to Perl 5's default set.

"Impossible?"

Someone, somewhere, at some point, maybe possibly defined a function named module or class with the exact prototype to make parsing that code ambiguous if that code ever runs unmodified on Perl 5.12 by accident and no one ever notices until it breaks, and it's more important that that one program we don't know exists remain working into the far future than to make life easier for every other Perl 5 programmer that we do know exists, because we are they.

I wish I were making this up.

chromatic wrote:

chromatic's status on Thursday, 17-Dec-09 02:52:41 UTC

Why yes, that *would* be a good idea, but it might break imaginary code: http://ur1.ca/i0hp

Abigail wrote:

My incantation has been ^AP for a long time. After all, I'm a programmer, and hence it's fairly trivial to make an editor macro that pastes in whatever I think is the best way to start a Perl program or module. And guess what, my best way doesn't match your best way. If "use 5.12;" called the pragmas you want, I still would have to invoke pragmas. And if "use 5.12;" invoked the pragmas I want, you still have work to do.

I'm very satisfied the way Perl currently works.

Theory wrote:

Replies

@Jakub—perl5i does not help with lexical scoping or shipped modules.

@Steffen—Does that incantation make utf8 the default for all IO in my module, too? And what pragmas are going to be added in the future that I'll have to consider using? How will they conflict with the existing ones. I want the madness to stop!

@Sylvain—That would be an improvement, yes, as long as there were some reasonable defaults. If there was a default I didn't want, it'd be good to remove it with a leading - or something.

@Sean—what chromatic said.

@Abigail—Then you can keep using Perl 5.10. I want things to improve, not stay the same, and I want Perl to become a better language for experienced Perl developers like you and me, not just stay static for language n00bs. And those n00bs need some help with reasonable defaults anyway. I'm glad strict will be on by default when you use 5.012;, it's a start, but even more reasonable defaults can be added to the language.

Please, let's have some convention over configuration without eliminating configuration. The conventions have changed; Perl needs to keep up.

—Theory

name wrote:

huh?

"I want things to improve, not stay the same,..." No, you want things to change in some ways, not stay the same in those ways.

Theory wrote:

Re: huh?

No “name,” you misread me. Please try again.

—Theory