develooper Front page | perl.perl5.porters | Postings from December 2021

Re: "no snails"; or having signatured subs complain about @_

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
December 8, 2021 21:13
Subject:
Re: "no snails"; or having signatured subs complain about @_
Message ID:
YbEf+tj0Pvfe+rO2@etla.org
On Tue, Dec 07, 2021 at 09:59:28AM +0000, Dave Mitchell wrote:

> 1) subs compiled within the scope of 'use signatures' don't get @_
> populated: @ is still the @_ of the caller. There is no separate pragma or
> other switch to allow this to be dis/enabled on a per-sub basis: if it's
> a signature sub, it doesn't get @_, full stop. Otherwise we'd have to have
> two code paths, two sets of tests etc for everything.

If you want @_, don't use signatures.

We're not going to be removing "classic" subroutines.

This is perl - "There's more than one way to do it."

*but* given that classic subroutines are staying, and need to stay
unchanged, permitting signature subroutines to have *two* modes of operation
gets us to *three* ways of subroutines operating, but only two different
functionalities. That seems redundant.


So I'm favouring your plan both from a design/readability point of view,
as well as an implementation/speed point of view.

> 2) Within the lexical scope of a signature sub (but not in the scope of
> e.g. nested signature-less anon subs etc), use of @_ and $_[X] is a
> compile-time warning. This should catch most coder errors associated with
> converting existing subs to use signatures.
> 
> If someone needs to populate @_ (e.g. for tail call recursion) it can be
> done as, e.g. :
> 
>     {
>         no warnings 'snails'; # or whatever the real warning name is
>         local *_ = [ qw(my new args) ];
>         goto &foo;
>     }

I'm still wondering, could we write that just like this:

    {
        local @_ = qw(my new args);
        goto &foo;
    }

and have the `local @_` disable the warning/error.

*yes*, this does seem to create what is actually a special case - `local @_`
is having some pragma-like effect, which `local @anything_else` does not.

but if you didn't *know* about the need to special case, that code is
much more readable. It's clear what it does, without having to know what
this "snails" is all about.

> 3) In the short term, if people still need access to @_, they can always
> stick with using a traditional sub for now. In the longer term, my

NO WAI!¡‼!

I'm sure that Perl's motto is something about "one, preferably only one
obvious way to do it" and once we have signatures, then obviously "classic"
subs must be deprecated, or at least discouraged, because that is the way
that we roll round here. Which means we need it all, and we need it all
now.


Or, if the first sentence of that paragraph is a load of bollocks, then I
think that the second is too.


> 4) In terms of implementation, the only logic that should go in
> pp_entersub() is checking a flag on the CV to see if it's a signatured
> sub. If so, it uses a pre-existing code path - the '&foo;' call mechanism.
> All the other logic should go in the sub itself - initially just as extra
> code in the OP_ARG* ops; later additions will add extra ops, and sometime
> after the sig implementation is complete, the optimiser will convert a
> suitable series of OP_ARG* ops into a single OP_SIGNATURE op which
> processes all args.


Right. And that's your the Perl-space design is the way that it is - because
pp_entersub() is already a performance pain point, and crafting a design
that adds the absolute minimal changes has almost not speed hit.

Nicholas Clark

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About