Mailing List Archive

1 2  View All
Re: PSC #049 2022-01-07 [ In reply to ]
On Sun, 16 Jan 2022 at 11:30, Tom Molesworth <tom@deriv.com> wrote:

> On Sun, 16 Jan 2022 at 16:44, demerphq <demerphq@gmail.com> wrote:
>
>> On Sun, 16 Jan 2022 at 09:12, Tom Molesworth via perl5-porters <
>> perl5-porters@perl.org> wrote:
>>
>>> To recap the original problem: someone who learns Perl-with-signatures
>>> who wants to pass a callback to a CPAN module will be writing fragile code.
>>> This is something that library authors have no control over. The suggestion
>>> is "library documentation should tell developers that they must always
>>> include , @ in callbacks".
>>>
>>
>> If those callbacks do not share a common signature then yes, that is what
>> they must do. I dont understand why you assume that any case where
>> callbacks are used will have inconsistent signatures. It seems to me that
>> it is equally likely most callbacks would be the other way around. Eg,
>> favoring one case or another is an arbitrary decision that comes down to
>> some external factoid about the situation.
>>
>
> hmm - I think the external factoid here would be "was written for the
> earlier version, before the new option was added"? There's momentary
> convenience in being able to leave out the parameters without the `,@`, but
> that's not really the focus. At the time the original code was written,
> signatures would presumably be consistent - there's only one case, the
> documented API with however many callback parameters were passed at the
> time, so there's no decision or favouring involved...
>

Ok, I see where you are coming from, i got it in my head before, but your
clarication moved that to the heart, if you know what I mean. I do see that
this would be quite irritating a major blocker to rolling our a new API
version with enhancements over a previous version. Old code that used to be
"just fine" would break because it doesn't accept the new parameter.


>
> From your questions here, I get the impression that perhaps you're still
> not clear on exactly what type of situation is problematic?
>

FWIW, I think I did, but the clarification is still helpful, it drives home
the point well.


> Just in case, here's a trivial example:
>
> Let's say we have a module X that provides `->each(sub ($item) { ... })`
> as a method. Perhaps it has an array-like structure internally and allows
> you to iterate over items.
>
> As code builds up over time, such as `$obj->each(sub ($item) { say "Item:
> $item" })`, everyone's happy, there may be an obscure note in the
> documentation about putting in `, @` in the signature somewhere but things
> work fine without that, and half the developers using this don't understand
> what that meant (or didn't read it in the first place). This module starts
> to occupy a key position in the CPAN dependency stream, and everyone loves
> it...
>
> ... except for one unsatisfied customer who points out that this isn't
> useful enough in the current state: it should also pass the index. They
> raise a patch supporting their very-important usecase: `$obj->each(sub
> ($item, $index) { say "Item $item had index $index" })`.
>
> Maybe all the tests already have the `,@` as advised, maybe tests are
> updated to fix everything that broke... either way, that new version is
> released. Anyone who upgrades and *didn't* put in that `,@` now faces
> breakage: they have to go and update all their code to cope with it. You
> might say that they should have read the documentation, that upgrades need
> careful testing, or that they are just bad programmers who should have
> written perfect code in the first place. Either way, there's unhappiness
> and perhaps a tendency to look again at other languages like Javascript
> where this type of extensible callback API change is comparatively easier.
>
> If the fallout is too bad, the change may be reverted, perhaps a new
> method is added - `->each_with_index`. Huffman proponents declare that the
> library is now unusable and proceed to fork it or rewrite from scratch,
> much acrimony ensues, and in the middle of all that someone points out that
> we clearly needed a *third* parameter, a reference to the underlying
> arrayref so that you can look at items either side of the current one. This
> is seen as a welcome distraction and immediately the userbase fragments
> into 3 different camps: the document said ,@ so get used to it,
> `->each_with_index_and_arrayref`, and `->each(sub ($item, $index,
> $arrayref) { ... }, WITH_INDEX | WITH_ARRAYREF)`. Perhaps someone else
> proposes a `use Library ":v2"` to get the new behaviour, or puts in a
> try-catch-until-we-stop-seeing-signature-failure workaround. The resulting
> discussion becomes heated and is posted on various social media outlets,
> with wise and informed commentary on all sides, but for some strange reason
> the development on that original library is slowing down a bit, and perhaps
> it's just a tiny bit less popular than it once was.
>
> Anyway, you get the point. As a developer, I'm left thinking "if I can do
> various boundary-breaking things like inspecting the caller's lexicals via
> PadWalker, then _not_ being able to check what a coderef expects to be
> called with seems like an odd omission".
>

Yeah im with you, a seemingly reasonable policy decision permutes into a
bundle of secondary problems that it need not.


>
>
>> FWIW, I used to have *very* strongly *aligned* views with you about the
>> warnings coming from sprintf Avar introduced ages back. At first I loathed
>> that sprintf would warn if I passed in more arguments than it used. But
>> over time I found that it actually saved me from embarrassment more often
>> than it hindered my projects. Not exactly your point, but not exactly a
>> different one either.
>>
>
> Indeed so - and that's just a warning. This is a step further - it's a
> runtime error. And again, in the sprintf case you controlled the format
> string *and* the parameters, so it's understandable that you'd need to take
> responsibility for making those consistent.
>

Actually the case I had in mind was where an external caller provides a
format to a sprintf which is provided a set of arguments in a standard way.
So it's much closer to your use case than this. Probably less problematic
to work around however as you say its a warning not a fatal exception.



>
>
>>
>>> There are no tools or mechanisms offered to enforce this... so people
>>> will leave it out, and things will work. They will work until a new version
>>> of that library is released which now passes additional optional
>>> parameters: then they will break.
>>>
>>
>> Isn't this a question for the implementer of the callback mechanism?
>>
>>
>>> Providing a way for the library code to deal with that - an explicit
>>> opt-out for arity checking, *not* a change to the defaults across the rest
>>> of Perl - seems like a basic courtesy to developers. If we are outright
>>> rejecting that, I find that disappointing. More so if the given reason is
>>> "we've been discussing signatures for 7 years already", rather than any
>>> specific technical impediment.
>>>
>>
>> But doesn't the @ mechanism do that? Eg, if an author of an API that
>> takes callbacks as a parameter should document that the callback API might
>> change over time and thus all subs SHOULD have a @ in it?
>>
>
> The @ mechanism does not do that, though:
>
> > There are no tools or mechanisms offered to *enforce* this... so *people
> will leave it out, and things will work*. They will work until a new
> version of that library is released which now passes additional optional
> parameters: then they will break.
>
> Making it easier to be backwards-compatible would benefit both the library
> developers *and* the users.
>

Yeah I get you.


>
> Is there some introspective approach that would help here? Eg, if I was a
>> callback author and I could interrogate that the signature did not have a @
>> as its last clause then I could warn if someone supplied me a callback that
>> didnt satisfy.
>>
>
> Yes. From the original email in that thread:
>
> > If we had some sort of introspection we could do some kind of
> > `bounded_invoke( $callback, @args )` which would slice @args to no more
> > than the signature says it wants.
>
> Sadly the conversation drifted away from that original suggestion - I
> didn't see any technical discussion on it.
>

Hrm, it seems like that would be solution so rjbs could have what he thinks
is sensibel, and you could have what you think is sensible. If one could
introspect on the arity of a sub then to some level this could be avoided.
Eg, when the new framework accepts a sub designed for the old 1 argument
API, it could internally ensure that sub was called with 1 argument, and
call the subs intended for more than 1 argument as required. If you can't
introspect on the arity then you can not harden yourself for this. Eg, a
forward looking dev could say "my callback framework insists the callback
accepts a slurpy argument list" and warn or die when someone passes in one
that doesnt have artiy==-1 (-1 for infinity), and one less prescient could
do something else internally, something like:

my $arity=arity($sub_ref);
if ($arity == 1) {
$sub_ref->($key)
}
elsif ($arity < 0 or $arity == 2 ) {
$sub_ref->($key,$index);
}


>
>
>> Anyway, I see the problem you are worried about and agree it has merit.
>> But I'm not sure that the policy approach that rjbs is taking is
>> unreasonable either. Is there a middle ground that would satisfy?
>>
>
> There is, yes - options have been proposed, including:
>
> - introspection, as above
>

This seems reasonable.


> - provide a way to bypass arity checks for a specific call
>

Although I am not sure I can elucidate why I think this would be a bad
idea, I am intuitively sympathetic to those who think it is a bad idea to
be avoided.


>
> If the answer is "no, we are not providing any of those", and that's an
> official PSC decision, then there's not much more to be said. I have not
> seen that stated explicitly (yet!). Would be nice to have a summary in the
> archives explaining _why_ we aren't considering them - performance impact,
> for example.
>

Personally I cant understand why if perl can validate the arity of a sub we
cannot provide a mechanism to determine what that is at a code level.

While in this new PSC world I dont believe my opinion matters much, it at
all, I personally think you have case to go to rjbs and the PSC and say, "I
do not want to change the rules about arity, but I *do* think we should
provide a way to introspect on it", and I think rjbs might be a bit more
amenable to talk about it if he understand it wasnt the "bypass arity
checks" argument rehashed. I dont him that well, and we do disagree from
time to time, but IMO he is usually a pretty reasonable guy.

I am going to CC him on this, he can yell at me if he wants. :-)

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"
Re: PSC #049 2022-01-07 [ In reply to ]
On Sun, 16 Jan 2022 12:23:53 +0100
demerphq <demerphq@gmail.com> wrote:

> Hrm, it seems like that would be solution so rjbs could have what he
> thinks is sensibel, and you could have what you think is sensible.
> If one could introspect on the arity of a sub then to some level this
> could be avoided. Eg, when the new framework accepts a sub designed
> for the old 1 argument API, it could internally ensure that sub was
> called with 1 argument, and call the subs intended for more than 1
> argument as required. If you can't introspect on the arity then you
> can not harden yourself for this. Eg, a forward looking dev could say
> "my callback framework insists the callback accepts a slurpy argument
> list" and warn or die when someone passes in one that doesnt have
> artiy==-1 (-1 for infinity), and one less prescient could do
> something else internally, something like:
>
> my $arity=arity($sub_ref);
> if ($arity == 1) {
> $sub_ref->($key)
> }
> elsif ($arity < 0 or $arity == 2 ) {
> $sub_ref->($key,$index);
> }

...

> Personally I cant understand why if perl can validate the arity of a
> sub we cannot provide a mechanism to determine what that is at a code
> level.

> While in this new PSC world I dont believe my opinion matters much,
> it at all, I personally think you have case to go to rjbs and the PSC
> and say, "I do not want to change the rules about arity, but I *do*
> think we should provide a way to introspect on it", and I think rjbs
> might be a bit more amenable to talk about it if he understand it
> wasnt the "bypass arity checks" argument rehashed. I dont him that
> well, and we do disagree from time to time, but IMO he is usually a
> pretty reasonable guy.

((With my personal hat and not my PSC hat))

I've also been wanting (needing) an arity-inspection mechanism,
currently required to make Syntax::Keyword::MultiSub work.

Also in the presence of such a mechanism it would be possible to write
a little call-wrapper to call a sub with no more arguments than it was
expecting, even if I accept that it will *SILENTLY* discard extra ones:

sub call_no_arity ($code, @args) {
my $nmax = max_arity_of $code;
splice @args, $nmax, -1, () if defined $nmax;
return $code->(@args);
}

...

sub each ($code) {
...
call_no_arity $code, $item, $index, $context;
}

Could be used with any of the following, without error:

->each(sub ($item) { ... });
->each(sub ($item, $idx) { ... });
->each(sub ($item, $idx, $c) { ... });


That said, my ideal wish would be for arity-checking to appear as a
default-fatal exception from the caller's perspective; so the caller
could do something like:

sub each ($code) {
...
{
no fatal 'signatures::max_arity';
$code->($item, $index, $context);
}
}

To, within that small lexical scope, disarm the fatality of maximum
arity checking.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: PSC #049 2022-01-07 [ In reply to ]
I've put some concrete examples of arity-checking API functionality here:

https://metacpan.org/pod/Acme::Signature::Arity

in case anyone else is in a similar library-author situation, needs a
workaround, and we end up deciding "no, not needed as a core/builtin
feature".
Re: PSC #049 2022-01-07 [ In reply to ]
On Sun, Jan 16, 2022, at 6:23 AM, demerphq wrote:
> Personally I cant understand why if perl can validate the arity of a sub we cannot provide a mechanism to determine what that is at a code level.

I don't mind the existence of a "Sub::Util::arity_of" or something. (I'm not sure what return would be best, since it needs to handle:
* undeclared
* fixed number
* n or more
* n or more, but even/odd)
What I don't want is to change the behavior we have out of the box, or to further delay shipping this based on something that can be added in the future.

> I am going to CC him on this, he can yell at me if he wants. :-)

I mean, I read p5p, which got all the previous messages, too. ???? I will only yell if you spill my beer.

--
rjbs
Re: PSC #049 2022-01-07 [ In reply to ]
2022-1-17 4:15 Ricardo Signes <rjbs@cpan.org> wrote:

> On Sun, Jan 16, 2022, at 6:23 AM, demerphq wrote:
>
> Personally I cant understand why if perl can validate the arity of a sub
> we cannot provide a mechanism to determine what that is at a code level.
>
>
> I don't mind the existence of a "Sub::Util::arity_of" or something. (I'm
> not sure what return would be best, since it needs to handle:
>
> - undeclared
> - fixed number
> - n or more
> - n or more, but even/odd)
>
> What I don't want is to change the behavior we have out of the box, or to
> further delay shipping this based on something that can be added in the
> future.
>
> I am going to CC him on this, he can yell at me if he wants. :-)
>
>
> I mean, I read p5p, which got all the previous messages, too. ???? I will
> only yell if you spill my beer.
>
> --
> rjbs
>

I have the same thinking as Tom about possible accidents.

My proposal makes arity checking optional.

use feature 'no_arity_check';

- Don't break anything, including experimental ones.
- Users can bypass arity checks. This is convenient because users can
rewrite the existing codes using signatures without changing any behavior.
- If we want to implement multi-sub in the future, use subroutines that the
arity checking is enabled.
- Subroutine arguments are used by everyone, so it should be selectable.
Coexistence of those who like arity checking and those who do not.
- There is no need to postpone the release of the current signatures.
- This way is very easy. Remove only ops of "... if @_> ..." "... if @ <
..." and "... if @_ % 2 != 0" when enabling "no_arity_check"
- A little faster than with arity checking.
Re: PSC #049 2022-01-07 [ In reply to ]
On Sun, Jan 09, 2022 at 11:33:29AM -0500, Ricardo Signes wrote:
> On Sun, Jan 9, 2022, at 7:37 AM, Neil Bowers wrote:
> > Our overriding desire is to get signatures "out there", but what's the right next step? There are at least 4 options:
> > 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.
> > 2. As for 1, but also add a runtime warning if you touch @_ inside a signatured-sub.
> > 3. Like 2, but touching @_ is fatal.
> > 4. Inside signatured-subs @_ becomes non-special.
>
> I am strongly in favor of #1.
[snip] stuff

There seems to be a lot of confusion and misconceptions present in this
thread.

My preferred solution consists of doing all of the following:

1) leaving @_ untouched when calling a signatured-sub (i.e. it is still
the @_ of the caller).

This will have a significant performance boost, especially when calling
small stub functions like accessors. At the moment perl has to do the
equivalent of

my @args = (...);
local *_ = \@args;

for every sub call (even ones without args), setting up, aliasing,
unaliasing etc. It will also make assigning args to parameters faster.

Eventually over time as signatures become the norm, @_ will be remembered
just as some old weird thing perl used to do (like we occasionally
encounter perl4-isms).

2) To detect signature code which relies on @_ from breaking with this
change, we also make the presence of @_, $_[...] etc within the *lexical
scope* of a signatured sub a *compile* time warning. This is relatively
easy to do (at least to catch most common cases) and has exactly *zero*
run-time performance issues.

I think a warning (rather than being fatal) is best - it's compile time so
will catch most things during development, but still allows legitimate
uses of @_, e.g.:

sub foo($x) {
....;
no warnings 'snails';
local @_ = (1,2,3);
goto &bar; # tail call optimisation
}


3) to allow introspection and other processing of the args, introduce a
new mechanism - either my 'query parameters' proposal or something else.

(3) can be done later as long as we're happy with the argument that "for
now, people should stick with the old sub syntax if they want access to
@_".


I would be strongly opposed to any final decision which didn't include
(1) and (2).

I would be uncomfortable with signatures becoming non-experimental until
both (1) and (2) were done.

I could live with (2) being done before (1). So I might accept:

5.36: - @_ gives compile-time warning of "don't use @_, subject to change".

5.38: - @_ gives compile-time warning of "don't use @_, no longer does what
you think it does";
- @_ stops being populated (i.e. it becomes still just caller's @_).
- signatures stop being experimental

5.40: - query parameters (or similar) added.

5.40+ other signature features like named signatures added piecemeal.


Note that if (2) happens before (1), I think the warning shouldn't be a
deprecation warning - we don't want the category of the warning changing
after we implement (1). (Which, thinking about it, makes me more keen that
(1) and (2) happen together).





--
Decaffeinated coffee is like dehydrated water
Re: PSC #049 2022-01-07 [ In reply to ]
> On Jan 17, 2022, at 07:31, Dave Mitchell <davem@iabyn.com> wrote:
>
> On Sun, Jan 09, 2022 at 11:33:29AM -0500, Ricardo Signes wrote:
>> On Sun, Jan 9, 2022, at 7:37 AM, Neil Bowers wrote:
>>> Our overriding desire is to get signatures "out there", but what's the right next step? There are at least 4 options:
>>> 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.
>>> 2. As for 1, but also add a runtime warning if you touch @_ inside a signatured-sub.
>>> 3. Like 2, but touching @_ is fatal.
>>> 4. Inside signatured-subs @_ becomes non-special.
>>
>> I am strongly in favor of #1.
> [snip] stuff
>
> There seems to be a lot of confusion and misconceptions present in this
> thread.
>
> My preferred solution consists of doing all of the following:
>
> 1) leaving @_ untouched when calling a signatured-sub (i.e. it is still
> the @_ of the caller).
>
> This will have a significant performance boost, especially when calling
> small stub functions like accessors. At the moment perl has to do the
> equivalent of
>
> my @args = (...);
> local *_ = \@args;
>
> for every sub call (even ones without args), setting up, aliasing,
> unaliasing etc. It will also make assigning args to parameters faster.
>
> Eventually over time as signatures become the norm, @_ will be remembered
> just as some old weird thing perl used to do (like we occasionally
> encounter perl4-isms).

The points heretofore raised in response to this seem to be:

1) There is no viable branch currently that implements leaving @_ untouched.

2) The performance gain has yet to be shown.

I’d love to help in either of these regards, but I lack the knowledge to assist with #1, and #2 can’t happen without the former.

-F
Re: PSC #049 2022-01-07 [ In reply to ]
On Mon, 17 Jan 2022 09:55:34 -0500
Felipe Gasper <felipe@felipegasper.com> wrote:

> 1) There is no viable branch currently that implements leaving @_
> untouched.
>
> 2) The performance gain has yet to be shown.
>
> I’d love to help in either of these regards, but I lack the knowledge
> to assist with #1, and #2 can’t happen without the former.

Working on it... Hope to have results later today.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: PSC #049 2022-01-07 [ In reply to ]
Hi Dave,

This is written as Neil, not a PSC position.

How about the following tweak to your proposed timeline?

1. 5.36: compile-time warning on use of @_ in signatured-subs, AND make signatures non-experimental
2. 5.38: @_ stops being populated; change wording of compile-time warning

This would give us non-experimental signatures a year earlier, and we’d have been warning about the impending change for a year as well.

I realise this slightly breaks the spirit of perlpolicy, but this isn’t proposing a change to signatures themselves. Perlpolicy also says "we'll always do our best to smooth the transition path for users of experimental features".

If we want people to continue to use Perl, and even new people to start, we need to move things forward, and signatures is probably one of the best things we can deliver in 5.36. And if we don’t get around to non-population-of-@_ in 5.38, well at least we made signatures non-experimental in 5.36.

You might argue, "Neil, you don’t know what you’re talking about", and to a close approximation you’d be right, but I feel like I need to lobby on the behalf of regular Perl developers.

Cheers,
Neil
Re: PSC #049 2022-01-07 [ In reply to ]
??, 17 ???. 2022 ?. ? 15:32, Dave Mitchell <davem@iabyn.com>:
>
> 1) leaving @_ untouched when calling a signatured-sub (i.e. it is still
> the @_ of the caller).
>
> This will have a significant performance boost

While it does, as-is it breaks stack traces. Without stack traces,
debugging becomes a pain. Unless any proposal for (1) also includes
solution for stack traces, it makes programmer's life worse, not
better.

Best regards,
Sergey Aleynikov
Re: PSC #049 2022-01-07 [ In reply to ]
On Mon, Jan 17, 2022, at 7:31 AM, Dave Mitchell wrote:
> On Sun, Jan 09, 2022 at 11:33:29AM -0500, Ricardo Signes wrote:
> > On Sun, Jan 9, 2022, at 7:37 AM, Neil Bowers wrote:
> > > Our overriding desire is to get signatures "out there", but what's the right next step? There are at least 4 options:
> > > 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.
> > > 2. As for 1, but also add a runtime warning if you touch @_ inside a signatured-sub.
> > > 3. Like 2, but touching @_ is fatal.
> > > 4. Inside signatured-subs @_ becomes non-special.
> >
> > I am strongly in favor of #1.
> [snip] stuff
>
> There seems to be a lot of confusion and misconceptions present in this thread.

I am always glad to see either or both of those things cleared up!

> 1) leaving @_ untouched when calling a signatured-sub (i.e. it is still the @_ of the caller).
> [...]
> 2) To detect signature code which relies on @_ from breaking with this change, we also make the presence of @_, $_[...] etc within the *lexical scope* of a signatured sub a *compile* time warning. This is relatively easy to do (at least to catch most common cases) and has exactly *zero* run-time performance issues.
> [...]
> 3) to allow introspection and other processing of the args, introduce a new mechanism - either my 'query parameters' proposal or something else.

So far, I think I'm with you. (I guess that the idea here is that behavior that can't be detected at compile time won't issue a warning at runtime, right?)

> I would be strongly opposed to any final decision which didn't include (1) and (2).
>
> I would be uncomfortable with signatures becoming non-experimental until both (1) and (2) were done.

I have mixed feelings about both 1 and 2. I'd like to see the actual performance change. That said, I acknowledge generally what we said we'd be doing.

But we've said that for years, now, and it hasn't happened and signatures have remained an experiment. Without a change in hand, showing that we have the changes prepared and know they'll work, it feels like "we kept this in experimental for years, planning to do this. We didn't do it, but this year is different." Is this year different?

There are at least three possibilities ahead of us:

1. we ship signatures as non-experimental this year
2. we ship signatures as non-experimental next year, and it's faster and a little different
3. we skip #1 in favor of #2 but do neither

What I want most of all is to avoid #3.

Our policy on experiments is:
> Experimental features will only have their experimental status revoked when they no longer have any design-changing bugs open against them and when they have remained unchanged in behavior for the entire length of a development cycle.

So if we want to change how @_ works and then make the feature stable, we're obliged to get that change into 5.even.0 so we can release it as non-experimental in the next stable .0 release. Could we bend the rules? Yes, but all the better if we can get this change into 5.36 if we want stable in 5.38.

In fact, this is what I proposed (with a difference in the phase in which warning occurs) in November: http://markmail.org/message/23qppsq4qjmegq6m

…but it's January now, which makes me start to worry that we're not 1.5yr from stable signatures, but 2.5yr, or more worryingly, 1.5 plus n. This is also why I've said it seemed practical to look at shipping stable now with a warning that one aspect could not be relied upon. If no actual changes to the @_ handling were produced, we'd be in a better place. If they were, we'd have given warning.

When 5.36 comes out, it will be eight years since signature were added to the language. I just want to feel like I can tell people to use them without feeling like a hypocrite, because I also tell people we need to act like experiments are really unreliable.

--
rjbs
Re: PSC #049 2022-01-07 [ In reply to ]
On 1/17/22 12:39 PM, Neil Bowers wrote:
> Hi Dave,
>
> This is written as Neil, not a PSC position.
>
> How about the following tweak to your proposed timeline?
>
> 1. 5.36: compile-time warning on use of @_ in signatured-subs, AND make
> signatures non-experimental
> 2. 5.38: @_ stops being populated; change wording of compile-time warning

Neil,

Just to be clear: Does this mean "@_ stops being populated in
subroutines using signatures? (As distinct from *all* subroutines).
>
Re: PSC #049 2022-01-07 [ In reply to ]
On Mon, Jan 17, 2022, at 12:48 PM, James E Keenan wrote:
> Just to be clear: Does this mean "@_ stops being populated in subroutines using signatures? (As distinct from *all* subroutines)

(I am not Neil but: yes. We can't stop populating @_ in other subroutines without breaking absolutely enormous amounts of code.)

--
rjbs
Re: PSC #049 2022-01-07 [ In reply to ]
On Mon, Jan 17, 2022 at 08:41:24PM +0300, Sergey Aleynikov wrote:
> ??, 17 ???. 2022 ?. ? 15:32, Dave Mitchell <davem@iabyn.com>:
> >
> > 1) leaving @_ untouched when calling a signatured-sub (i.e. it is still
> > the @_ of the caller).
> >
> > This will have a significant performance boost
>
> While it does, as-is it breaks stack traces. Without stack traces,
> debugging becomes a pain. Unless any proposal for (1) also includes
> solution for stack traces, it makes programmer's life worse, not
> better.

It doesn't necessarily break stack backtraces; that is an entirely
separate choice. It boils down to (on non-@_-setting) sub calls, whether
we leave the original args on the stack or not. At the moment the args are
popped off the stack but stored in @_ instead.

The current behaviour means that for deeply nested sub calls with many
arguments, the stack doesn't tend to grow much, but lots of subs get their
private @_'s AvARRAY array of pointers left grown.


As an extreme example, this code

sub recurse {
return if $_[0]-- < 0;
recurse(@_);
}
recurse(10, 1..1_000_000);

would currently:
expand the stack by 1M pointer sizes (so 8Mb)
create 10 permanent (but private) @_'s (one for each depth of
recursion) each with a 1M pointer size buffer that is never freed.

When removing @_, we could either:

1) leave the arguments on the stack:

- this makes @DB::Args continue to work, and changes the memory usage to:
expand the stack by 10M pointer sizes (80Mb)
(there are no @_'s using memory)

2) pop the stack after processing args:

- this breaks @DB::Args (and thus stack backtraces), and changes the
memory usage to:

expand the stack by 1M pointer sizes (so 8Mb)
(there are no @_'s using memory)

So we have a complete choice. Leaving the args on the stack (and
thus not breaking stack backtraces) would result in a larger maximum stack
growth (which can then be reused for different sub calls) compared with
now where we have smaller stack growth, but leave lots of @_ buffers
lying around which can only be reused if *those* subs are called again.

--
This is a great day for France!
-- Nixon at Charles De Gaulle's funeral
Re: PSC #049 2022-01-07 [ In reply to ]
On Sun, Jan 09, 2022 at 12:37:32PM +0000, Neil Bowers wrote:
> The topic we've discussed a lot recently is what to do with @_ in
> signatured-subs:

A few more facts I've just remembered to chuck on the fire.

1) Another advantage of not populating @_ is that it removes a whole bunch
of edge cases concerning what happens if @_ is modified during arg
processing. In particular things become more complicated if we ever
implement named args: this is where the caller does foo(y =>2, x =>1) to
call sub foo(:$x, :$y) {} - here the processing of default args etc
doesn't follow a simple L-R ordering and it's more likely that @_ could
get modified mid-processing.

As well as confusing or undefined behaviour, it requires more arg
processing overhead, because for example the size of @_ needs to be
rechecked after each arg, in case it has shrunk or grown in the meantime.

2) Some miscellaneous behaviours we may want to pin down before making
signatures non-experimental.

a) we should more clearly document the ordering of side effects (such as
calling FETCH() on tied values), or more to the point, document what
things are officially undefined, giving us more flexibility to change
things later when optimising.

b) banning of goto's into and out of default blocks:

we currently warn when entering a block containing a default expression:

Use of "goto" to jump into a construct is deprecated at ...

Perhaps that should be upgraded to a fatal error.
Jumping into the main block of a sub from a default expression doesn't
currently warn - maybe this should become a fatal error?

sub foo2 ($x = do { goto MAIN }, $y = ...)
{
MAIN: print "in main body\n";
}

c) decide where whitespace is is allowed or forbidden: this is currently
legal:

sub foo ($ x) {}

I think it would be nice to make it a compile-time error.

d) should duplicate parameters be a compile error? (at the moment it just
warns):

sub f ($a,$a) { ... }

"my" variable $a masks earlier declaration in same scope


Having now remembered a bunch of stuff in addition to @_ which might effect
experimentality, I'm leaning more strongly towards:

5.36 - make use of @_ a compile-time warning;
- fix up the other stuff mentioned above if we have time.

5.38 -stop populating @_
- make signatures non-experimental if we feel confident, else defer
for 1 more release.

5.40+ add new signature features.




--
Modern art:
"That's easy, I could have done that!"
"Ah, but you didn't!"

1 2  View All