Front page | perl.perl5.porters |
Postings from April 2021
Re: on changing perl's behavior
From: Ricardo Signes
April 4, 2021 03:08
Re: on changing perl's behavior
Message ID: firstname.lastname@example.org
No, I didn't fall off the list! Between some non-Perl obligations and waiting on talking to the rest of the steering council, this email has been waiting to get written. (Also, I allowed myself to enjoy the long weekend a little!)
In my last long email, I was writing about the conflicts between:
* wanting it to be easy to have "the best perl" to write in
* wanting your existing, working code to keep on running without edits
…and other related tensions.
One thing that we talk about a lot is "use vX". The idea behind "use vX" is that it gives you a one-stop shop to say "give me the best set of defaults [according to p5p consensus]", and that this set of defaults can be left intact indefinitely so that ten years down the line, a program that said "use v5.12.0" can still run with largely unaltered behavior. I say "largely" unaltered, because we have altered it. The use of `qw(...)` as if it was `(qw(...))` was deprecated and removed, for example. This allowed for simplification of the language implementation, and we could do it even though using "qw" in this way was never guarded by a named "feature". We warned that the feature was going, then we deleted it and smoothed out some wrinkly code.
The same thing could be done again for, say, indirect object syntax. When encountered, perl could begin warning now, and then in a few years, it could be fatal. In theory, this could simplify the grammar. I think that this mechanism (deprecate, then remove) is *orthogonal* to the addition of feature guards. Being able to lexically disable indirect object syntax is a help to programmers who know they will never *want* to use it. It is not a direct path to removing the feature — but it can be helpful on that front. That is, as more people disable indirect syntax by default, the idea of removing it becomes more palatable.
So this may be an accurate set of statements about how we've done things so far:
* 1: We make new behaviors opt-in when they would break existing code if on by default.
* 2: We make new behaviors on by default if they could not appear in existing, working code.
* 3: We remove behaviors when they are making the language implementation harder to work on *and* cause only acceptable amounts of inconvenience.
* 4: When a behavior is going to be removed, it first issues a deprecation "this is being removed!" warning for several versions.
* 5: We make old "bad" behaviors lexically optional when we think people will (or should) want to turn them off by default in new code. (I would argue that this is exactly what "use strict" did in v5.0.)
* 6: We bundle all the options (both opt in and opt out) in "use vX" to make it easy to get them all.
I think some of the discussion of new defaults and future perl changes have also had these things in mind:
* 7: We will alter the default opting in or out of behaviors over time, so that the starting position is closer to the ideal.
* 8: When a default behavior is going to be changed, encountering the behavior when no opt in/out has been explicitly performed, a warning is issued, giving the user a nudge to either add a "use feature" or to update their code.
Item 6 is built on the idea that writing a bunch of boilerplate is bad, and writing close to zero is better. Item 7 says "zero is better than nearly zero." But it *also* says "just adding vX to my code is a bridge too far."
That is: "I want all my code to have strict, warnings, no indirect object syntax. I believe any violation of this is a bug on my part, and I want it applied everywhere." Turning on "use strict; use warnings; no feature 'indirect'" everywhere gets exactly that. Saying "use vX will turn all that on [and a bunch of other stuff you don't know how to evaluate]" is not necessarily a big win. If an organization wants to have a standard boilerplate, and users see "we run perl-5.20, but use v5.20 turns on unicode strings, and I don't know what that does to my existing code, but I know that it sounds scary", then they are not likely to add it to their old code. And once it's not in their old code, will it become standard in their new code?
I think that item 7, above, is (in part!) built on this concern. "Users are never going to go back and add one of our big omnibus feature bundles. We can't possibly turn all that stuff on without their opting in. On the other hand, we can guarantee that every program running meets these minimal criteria with zero edits to the source by just changing those defaults. Only already-bad code will be broken."
There are a few assumptions built into that. Most often objected to: the assertion that code that does not say "no strict" and then violates strictures is bad. But other points worth considering: "users don't want to use vX because they don't know what it does" and "users don't want to add use vX to old code [for the same reason]" and "I want to know that all my code follows the same rules out of the gate without chasing up any set of use statements everywhere."
And built into *that* is the question of "my code". Is that "all the code we run" or "all the code we run *that we wrote*."
*Anyway:* I'm not going to address all of that now and act like I have an answer that will please everyone. I do think it's at least a bunch of the "new defaults" argument broken down into pieces.
My question is more like this: We assume that "just start all code with use vX" is workable for new code. What can we do to encourage users to feel good about how they take their existing, running code and get it up closer to "the best perl we know" options? Here, I'm assuming that there's a lower cost of ownership to your code if you can know that all your code can be skimmed the same way, because it's got the same set of options. But you now want to take your older code and stick the same use vX at the top as you have in your new code. How do we help users feel confident in staying up to date with the "use vX" of their current perl-X?