develooper Front page | perl.perl5.porters | Postings from January 2022

arity checking (was Re: PSC #049 2022-01-07)

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
January 21, 2022 13:12
Subject:
arity checking (was Re: PSC #049 2022-01-07)
Message ID:
YeqxPjbT1DJZ1hM4@etla.org
This might seem flippant or obvious but it's not:

There is only one perl core, so it can only have one default.


Whereas different use cases often benefit from different defaults.

(And different people have different common use cases. And this isn't a
problem with modules on CPAN, as there can be more than one module to solve
the same problems.)

On Sun, Jan 16, 2022 at 11:58:00AM +0000, Paul "LeoNerd" Evans wrote:
> On Sun, 16 Jan 2022 12:23:53 +0100
> demerphq <demerphq@gmail.com> wrote:

I think that this is the key insight:

> > If one could introspect on the arity of a sub then to some level this
> > could be avoided. GEg, 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);
> > }


> 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.

Why is maximum arity checking special?

Am I also allowed 

      no fatal 'signatures::min_arity';

to disable minimum arity checking?

I'm not sure if *that* is useful, but constraints as flat text in package
names doesn't scale up. "Does it take a slurpy hash?" is also a question
that calling code might care about, and how many positional parameters
before said hash, because that can be a way to extend APIs.


Really you want to know you have a problem *before* you call the callback
(ie what Yves wrote - you want to be able to flag a problem at object
construction time, which might well be program startup. Not fail at runtime,
unattended, into a log file or even /dev/null)

and generally I thought it was considered that exceptions should be for
things that went wrong, not control logic



Also, *if* you have arity introspection (not just "no fatal"), you can
implement more nuanced support for changed callbacks, such as filling in
missing parameters, or calling the callback if the "missing" extra
parameter is undef, but hard failing if the caller needed to pass non-undef
but the "old style" callback would ignore it.




And I don't think that being able to turn of arity checks - ie some

    use feature 'no_arity_check';

really solves the problem. Because if the default default is strict arity
checks, then however much you document the API as "provide a callback that
accepts future extra parameters", someone using the API is going to get it
"wrong" and call it with a strict arity callback.

And it's all going to work (and pass tests) for months, until the time when
you extend the API (as planned and documented) and the client code that
passes a strict arity callback breaks. At runtime.


Hence I think that optional parameters (whatever syntax enables them) really
is just a band aid. At best it doesn't solve the underlying problem. At
worst it will create a false sense of security.

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