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 ClarkThread Previous | Thread Next