Mailing List Archive

Discourage @_ in signatured subroutine
I've started a branch to add a discouragement warning when people try
to rely on the @_ array inside a signatured sub:

https://github.com/Perl/perl5/pull/19346

For instance, while not using a signatured sub this is fine:

./perl -Ilib -Mexperimental=signatures -ce \
'sub f { my $self = shift; print @_; }'

-e syntax OK

If the sub has a signature it prints warnings at compiletime:

$ ./perl -Ilib -Mexperimental=signatures -ce \
'sub f($x) { my $self = shift; print @_; }'

Implicit use of @_ in shift is discouraged in signatured subroutine at -e line 1.
Use of @_ in print is discouraged in signatured subroutine at -e line 1.
-e syntax OK

The PR is still draft as it still needs a bit more work on it (see the
notes in the PR itself).

Notably, this relates to the recent "de-experimentalise signatures"
discussions in a few ways:

*) It's a compile-time warning, it has no runtime effect
*) It's only a warning, it does not change the current behaviour

To stress again - it doesn't alter any behaviour, other than printing
some warnings at compiletime. Runtime performance remains exactly as it
was, and any code that provokes these warnings still works as it
currently does.

Additionally, as it's simply a warning intended to draw attention to
"you probably don't want to do that" situations, it doesn't have to be
perfect and cover all the bases. In particular there is at least one
known situation that it can't see:

$ ./perl -Ilib -Mexperimental=signatures -e \
'sub f($x) {
my $splat = "_";
no strict 'refs';
my $y = shift @$splat;
print "x=$x y=$y\n"; }
f(123)'

x=123 y=123

It doesn't have to perfect. It just has to warn people who are dipping
their toes into signatures that we *may* change the behaviour of @_ at
some further point down the line, so they probably don't want to do
what they're currently doing.

I believe this still fits in with option 1 of our plan:

> 1. Remove the experimental sticker off signatures and release that
> way in 5.36 (so you'd still have to `use feature` or `use
> v5.36`), but no other changes.

because additionally, we can always add discouragement/deprecation
warnings at any time, without otherwise upsetting the "experimental"
status of a feature.


Thoughts, anyone?

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: Discourage @_ in signatured subroutine [ In reply to ]
On Sun, 16 Jan 2022 15:41:44 +0000
"Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:

> I've started a branch to add a discouragement warning when people try
> to rely on the @_ array inside a signatured sub:
>
> https://github.com/Perl/perl5/pull/19346

This is now ready for review/merge, but I'm suddenly unsure about one
detail: What should the warning category be?

I've currently put it in a new category called "discouraged", on the
thought that it is a bit similar to "deprecated" but not quite the same.

I'm suddenly unsure though, whether it would be better for this to have
its own category - perhaps called "snail" or something? I'm thinking of
a situation where, if we added other "discouraged" warnings of
unrelated things, whether someone might have done

no warnings 'discouraged';

to turn off these ones, then they wouldn't see those others. It perhaps
might be best for this particular category of problem (use of @_ in
signatured sub) to have its own warning category, to minimise the risk
of that collateral damage.

Thoughts?

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: Discourage @_ in signatured subroutine [ In reply to ]
2022-1-26 1:33 Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> wrote:

> On Sun, 16 Jan 2022 15:41:44 +0000
> "Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:
>
> > I've started a branch to add a discouragement warning when people try
> > to rely on the @_ array inside a signatured sub:
> >
> > https://github.com/Perl/perl5/pull/19346
>
> This is now ready for review/merge, but I'm suddenly unsure about one
> detail: What should the warning category be?
>
> I've currently put it in a new category called "discouraged", on the
> thought that it is a bit similar to "deprecated" but not quite the same.
>
> I'm suddenly unsure though, whether it would be better for this to have
> its own category - perhaps called "snail" or something? I'm thinking of
> a situation where, if we added other "discouraged" warnings of
> unrelated things, whether someone might have done
>
> no warnings 'discouraged';
>
> to turn off these ones, then they wouldn't see those others. It perhaps
> might be best for this particular category of problem (use of @_ in
> signatured sub) to have its own warning category, to minimise the risk
> of that collateral damage.
>
> Thoughts?
>
>
Personally, I can accept that signature subroutines don't use @_ in the
future release.

DaveM and Tony think that non-popurating @_ improves the performance of
signature subroutines.

I don't know the details, however I feel it is right.

If the argument count is needed in signature subroutines, we need to write
an array argument.

# Current subroutines
sub id {
my $self = shift;
if (@_) {
$self->{id} = $_[0];
return $self;
}
return $self->{id};
}

# Signature subroutines
sub id ($self, @value) {
if (@value) {
$self->{id} = $value[0];
return $self;
}
return $self->{id};
}

I can accept that Carp::confess doesn't get the information of the
arguments in the stack trace because the performance is more important for
me.