Front page | perl.perl5.porters |
Postings from June 2020
Re: Announcing Perl 7
From: Dan Book
June 27, 2020 16:47
Re: Announcing Perl 7
Message ID: CABMkAVUdXeu-h+dBkG1UCwrLX6-vQKZBA6_VpGhph46-dx77xQ@mail.gmail.com
On Fri, Jun 26, 2020 at 3:43 PM Sawyer X <firstname.lastname@example.org> wrote:
> > 'use v7' also allows the new stuff to be scoped to a single source file;
> > other .pm files can still be included unmodified using the old perl
> > syntax.
> That's actually far worse and is a major reason "use v" is not suitable.
Just to address this first: no, it is a major reason that "use v" is the
*only* suitable method. I will explain further.
> > Look, we've got this great built-in mechanism, 'use vx.y.z' that's been
> > around forever. It hasn't seen much use yet, because frankly there's
> > been very little call for it, since there hasn't been much new
> > non-backcompat stuff so far. But its been sitting there waiting for use
> > use it.
> This mechanism isn't in use because it does not work.
Instead, I will focus on one particular aspect: "use v" does not work for
> 1. People do not actually use "use v". This is what we've seen with it
> so far. CPAN is an example, and every code-base I touched and
> discussed with peers had rarely used it. It is true that this is
> anecdotal because I haven't touched or discussed every code-base, but
> I am in touch with a few major Perl shops. It is rarely used by any of
> them. This has to account for a fair portion of active Perl code and
> this anecdote does means something. We have a mechanism we believe is
> superior and gives our users what we think we want. Our users don't
> use it. Aergo, our mechanism isn't the gift to developers we thought
> it is.
I disagree, with both the premise and conclusion. It is in use, maybe not
always explicitly, but via modules doing the exact same thing. Mojolicious
currently provides the equivalent of "use v5.16" to all of its own and user
code, plus some other useful things like "use warnings" and "use utf8"
which we should really consider adding to the "use VERSION" functionality.
Any time which I could use "use VERSION" and did not, it was only because I
end up having to add an explicit "use warnings" anyway.
There are two things that can drastically improve the experience and
visibility of "use VERSION". One is making it set "use warnings", so that
it actually is a meaningful reduction in boilerplate, and then can be used
all over the docs and tutorials. The second is having meaningful major
versions as is being proposed, so that it is much easier to distinguish
what a "use v7" might allow you to use from what a "use v8" than the
difference between "use v5.14" and "use v5.24". None of this requires or
benefits from changing the default features.
2. "use v" turns on *everything* till this version. With 7.0, we do
> not intend to turn on everything. If you were to take a large
> code-base, you will not be able to easily transition it to
> *everything* in feature.pm. It's impossible, even with an exhaustive
> set of tests, because the number of changes, both to syntax and
> semantics, will require a lot of updating and probably tests you
> haven't even thought of. A good example is unicode_strings. If I had
> written 10K lines assuming my strings are bytes, I'm screwed. Will I
> get the time to actually go ahead and change all of my code to assume
> otherwise? Probably not. For 7.0, we will turn on very few pragmas and
> features, to allow people to make a relatively seamless update. This
> is already being tested with a few stakeholders and is proving fairly
This is a moot point unless we actually change the defaults, which I am
arguing is the error in this design.
3. "use v" being lexically scoped is even worse in this respect.
> Different code within the same code-base that touches the same data (a
> fairly common occurrence) will now have some lines of code that assume
> the string is bytes and some assume it is Unicode characters. This
> makes the code nearly impossible to work with. If in #2, I expressed I
> can't move a large code-base to every possible feature and pragma at
> once, the fact that it's lexical can only make it worse for me because
> I don't know if a line of code that has it enabled will trigger a line
> of code in a different package which doesn't have it enabled.
This is misleading. unicode_strings does not do this. unicode_strings
causes a specific set of functions in that lexical scope to use Unicode
rules when determining how they interact with a string, instead of possibly
using ASCII rules if the string is downgraded as the previous heuristic
did. This is completely incomparable to issues where the string *contents*
are actually different. It is exactly the usefulness of a lexically-scoped
feature, and I would argue that causing hard-to-detect problems is *more*
reason to keep it scoped lexically rather than affecting code that did not
expect it, particularly that you did not write.
> 4. "use v" is meant to make "use feature" easier. Using feature.pm
> indefinitely makes it impossible to ever remove code, which is also
> something we are actively trying to change. This means that "use v"
> does even more to cement feature guards' infinite existence. Why
> remove crufty features in the code when we can just keep it on by
> default and force all developers to indicate they don't want it?
This argument is self-defeating.
Let's take three example situations.
Situation A, I am writing or maintaining code where I can use an arbitrary
version of Perl for the features I wish to use. I probably am currently
using "use v5.20" for signatures already. I could just as easily change to
"use v7", as run that code on a version of Perl which enabled these
features by default; the default enabling of features does not impact me in
Situation B, I am writing or maintaining code that is developed for a
specific deployment of Perl. I may or may not be using feature bundles. If
I have not yet upgraded to Perl 7, then I cannot either "use v7" or use the
features that are default enabled. Once I decide to upgrade to Perl 7, then
I can either "use v7" or use the features that are default enabled, because
I know it will be running on that Perl for the time being. There is no
reason to use any compatibility module since it will only run on the
version of Perl it is being deployed to.
Situation C, I am writing or maintaining code which must continue to work
on older Perls, probably because it is for CPAN and I wish to be polite to
users. I cannot currently "use v5.32", because it would mean the code
cannot run on these older Perls, by definition. I also cannot write this
code using features that would be enabled by Perl 7, because using those
features without enabling them would mean the code cannot run on these
older Perls, and would not even have a nice error message to indicate this
problem. "use compat" only allows me to write code that will work with or
without these features enabled; it does not allow me to write code that
will work on Perls that do not have this feature to begin with.
I am sure there are other use cases with differing tradeoffs to make. But
taken together, I think that this shows that any argument against the
usefulness of "use v7" is also an argument against the usefulness of Perl 7.
> * With "use v" I need to add this *everywhere*.
With Perl 7 feature defaults, you need to expect it to affect *everywhere*.
> * With "use v" I need to deal with even significantly breaking changes
> and I need to deal with all of them at once. (Like within a
> single-but-large file.)
With Perl 7 feature defaults, you need to deal with significantly breaking
changes all at once, even in code you are using that you did not write, and
cannot lexically scope the changes until a particular part of the code is
* With "use v" I need to add this to all files and deal with all of it
> at once because due to it being in a package scope, it can create a
> vast action-at-a-distance behavior. I could trigger code within my
> code-base which wasn't updated or code in a module which wasn't
This is false. The effect of "use v" is entirely lexical.
> * With "use v" the code will not get removed, which is the opposite of
> what we want
I don't see how this proposal solves this problem any better. We are still
providing the mechanisms to turn these features off, and we will still have
the ability to remove support for features as we already do. The existence
of major versions allows us to do this more cleanly, regardless of enabling
them by default or not.
To summarize my overall point: I do not think that changing the default
enabled features sufficiently solves the stated problems, to justify the
amount of effort it will take to overcome the breakage it will introduce,
when compared with an improved "use v7" which does not introduce any
breakage and solves these problems as well.