FAQ
Here's the tl;dr version of what I propose below.

1) Annoying warnings that users want to turn off are indicators that
you're covering up a bad feature with another bad feature. Fix the bad
feature.

   1a) That I/O functions do not throw exceptions is a bad feature.

   1b) Make autodie default in 5.2x.

   1c) Make autodie a core pragma like strict to improve performance, add
missing features (like die on failed implicit close), and make it easier
to maintain.

2) Linters are complementary to core warnings. That's ok.

   2a) Perl::Critic does a great job, it could do even better.

   2b) Make it easier to do dynamic analysis in a CPAN module. Many
tools will benefit, including Perl::Critic.

3) Add verisoned warnings.

   3a) "use v5.x; use warnings;" is equivalent to "use v5.x; use warnings
':v5.x';"

   3b) Solves the "my code was working before and now it's throwing
warnings" upgrade problem.

   3c) Makes it easier to add new warnings, we don't have to have the
"what about old code" debate which is the whole point of the "use v5.x"
system.

On 6/24/14, 2:11 AM, Ævar Arnfjörð Bjarmason wrote:
FWIW I CC'd you because you proposed a warning for grep in void
context a while ago at:
http://www.nntp.perl.org/group/perl.perl5.porters/2007/12/msg131922.html

That got added to perl, and then removed again because it warned about
legitimate uses of grep as a loop.
Oh yeah. "legitimate". :P For the purposes of this discussion I am
using that to mean "some people used it as a shortcut, but there's
better ways to do that, and it was never considered good practice".

The idea of versioned warnings would fix that problem. Old code written
when grep in void context was considered "legitimate" will still work
silently. New code written with "use v5.x" will warn people going
forward against a confusing practice and maybe nudge them towards map in
void context or postfix for.

OTOH there really are some warnings which are quite annoying and
pedantic and often wrong. It would be nice if there were a way to turn
them off. The key here is turn them *OFF*. Not turn them on.
So you think that if I add a warning about print in void context to a
new perl release we should just turn that on by default, and field the
inevitable flood of confused people upgrading, rather than just
putting it in a category of its own with "extra noisy but possibly
useful" warnings that you can optionally enable?
I would argue that warning is a bad solution to the wrong problem.

Problem: Programmers aren't checking the error returned from print.

Solution: Remind programmers to check for that error with a warning.

There's a reason nobody checks for that error. 1) It's very rare. 2)
It's a PITA to sprinkle "or die" all over your code. This creates a new
problem.

New Problem: Programmers are turning off warnings because a few of them
are really annoying.

To find the problem with the solution, let's look at the problem with
the problem. Any solution of the form "admonish the user until they
change their behavior" is a bad solution and indicates you're trying to
cover up a design problem by blaming the user. Usually the user is
doing the obvious and simple thing, but the system is designed so the
obvious and simple thing is wrong.

The solutions to such a problem are often themselves annoying, which
create new problems as users try to circumvent the "solution". And
that's where this whole conversation is at. We're trying to find a
solution to the problem of users circumventing the solution to the
original problem. Got that?

That print (and open and close and system...) does not throw an error is
a questionable language feature. We know that. Questionable language
features should not be warnings. Questionable language features should
not be pushed off onto the user to fix with more scaffolding code or
admonished to "be more careful". Questionable language features should
be fixed.

The user is going to do the simple and obvious thing. Don't fight that,
you will lose. Make the simple and obvious thing correct. Enable
"autodie" for v5.2x. A real autodie built into the core which would
probably be easier than maintaining the existing Perl one. (I've tried
it myself, my C chops are not up to speed yet).

Then a failed print throws an exception. The need to sprinkle "or die"
around goes away. The need for an annoying warning goes away. Code is
safer by default. Coders are happier. The chain of questionable
features to cover up questionable features is broken.

But such a warning might still be useful
Such a warning is not a warning. Why? You don't leave it on at
runtime. You might turn it on once or twice during development and
eyeball the results. Most of the warnings will be utterly bogus.

That is a code audit. Things useful only in code audits, not in
production, go into a linter like Perl::Critic. More on Perl::Critic below.

Why turn them off? If these warnings are important enough that we feel
they should be in the core, rather than in Perl::Critic or something,
then it's important the programmer makes a conscious decision about
whether or not the warning applies to their code.
Perl::Critic keeps coming up in this thread, so I'm responding not
just to you but to others: Perl::Critic is *not* a replacement for
warnings in the core. Even for simple things like "is this in void
context", it can't handle code that's string evaled into existence, it
can't discriminate between code you *actually* run and mostly unused
code you just have lying around etc. It's complimentary to something
you'd add as a core warning e.g. because it can somewhat statically
analyze code you haven't run yet, it's not a replacement.
Yes, Perl::Critic is complementary with warnings as designed. That is
the role of a linter. It works pretty good.

Linters are also typically developed *outside* the control of the core.
  This is also complementary with core warnings. It allows a faster
development cycle and a different point of view.

The missing features you mention would be nice. They're largely because
Perl::Critic does static analysis. This is largely because PPI made
static analysis easy[er]. We know dynamic analysis in a Perl module is
possible, see also Devel::NYTProf and Devel::Cover, and given the
plethora of CPAN modules attempting to do it should be made easier.

Linters do not replace runtime warnings. Runtime warnings do not
replace linters. They are complementary. A linter is a release valve
for borderline and really finicky warnings, like print in void context.
  Does this contradict what I said earlier that "warnings should be
turned off, not on"? Yes. And that's how design rules work. :)
They're both good rules. Find the middle ground.

(And why are you evaling so much code that it's a major complaint about
your linter? Hmmmmm? ;P)

Warnings you have to turn on don't get turned on, not without years and
years of training the community. If it's not a feature they need to get
their job done, they're not going to seek it out to turn it on. People
can't make good decisions about warnings they never see and are never
aware of (no, you can't count on people reading perldelta).
Not everyone needs to know about how warnings work, if you're working
as a programmer on a large site someone will maintain and import a
pragma for you that imports the warnings useful there, if the core
provides a way to turn on warnings it'll be picked up by modules like
Modern::Perl, common::sense etc. I don't think we should necessarily
be in the business of *enabling* warnings in the historical warnings
pragma, it's sufficient that we provide a way to turn them and so the
CPAN can sort out the best interface for it.
There's a lot of "if" coming off that plan.

I reject the design principle that getting the basic language up to a
usable state can be so complicated you need an expert or CPAN module to
do it for you.

Simple questions should have simple answers. "How do I turn on all the
warnings" is a simple question. It should have, and does have, a simple
answer: "use warnings". It should not require more CPAN modules
encoding tribal knowledge. Perl should work safely by default out of
the box.

Furthermore, the idea that new programmers are working on a big team, or
with lots of connections to the community for code audits, AND that they
are doing best practices is bogus. In my experience, big teams are some
of the slowest to adopt good practice, especially if that involves
installing a CPAN module.

Tribal knowledge is a barrier to entry for Perl. I was just talking
with a librarian friend of mine. She wants to learn programming to
improve Koha, a library system written in Perl. While Koha is a large
project, she has no knowledge of programming, no community of peers to
interact with. I'm sure the Koha people are lovely, but she's unlikely
to reach out to them while learning to code. When she makes her first
patch, she will likely try to do it alone. There's all sorts of reasons
why that's counter-productive, but lots and lots of new programmers do it.

As for backwards compatibility, this problem with adding warnings
happens in EVERY version of Perl. If your code is so fragile that it
will freak out at new warnings, you're already doomed. But there's a
forward solution to that below.
[snip] that, but I like that API you're proposing, in particular not
duplicating version declarations in multiple places.
Hey! We agree on something! High five!

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

People

Translate

site design / logo © 2017 Grokbase