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

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

Thread Previous | Thread Next
From:
demerphq
Date:
January 21, 2022 17:29
Subject:
Re: arity checking (was Re: PSC #049 2022-01-07)
Message ID:
CANgJU+X6+Yr2jFs+2Wr=d4uUnWD86FqEPopdhAU3NBaszz=NOw@mail.gmail.com
On Fri, 21 Jan 2022 at 17:26, Dave Mitchell <davem@iabyn.com> wrote:

> On Fri, Jan 21, 2022 at 03:15:31PM +0100, demerphq wrote:
> > On Fri, 21 Jan 2022 at 14:12, Nicholas Clark <nick@ccl4.org> wrote:
> >
> > > 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)
> > >
> >
> > So am i correct in understanding that you would be ok with exposing an
> API
> > to check the subs arity signature? If so then I'll try to think up
> > one (others could too).
>
> But this is a general problem, not just one with signatured subs.


If you read the scenario that lead to this you will see that actually they
are very very different. One is a "doctor it hurts when is stick a fork in
my eye", and one is a "doctor it hurts when YOU stick a fork in my eye".

So consider, I own a framework whose api is that I accept a callback from
the caller. I tell the caller that my api will call his sub with 1
argument, lets say "key".

You write a callback which takes one argument, and you pass it into the
framework. All is good.

Later on I get a request from a user to pass in two arguments to the
callers, "key" and "idx".

With the unsignatured subs UNLESS you put the guard clause you just stated
into the callback all will be good. Old users of the api will continue to
work as they will just ignore the new argument. New users of the api who
are aware of the new parameter will get the argument and all will be good.

But with signatured subs all of a sudden the old users will break as they
violate the arity check. And the framework can't "defend" against this by
validating the signature. So basically signatured subs become useless in a
callback api without a way to introspect the artity.



> A
> "normal" callback sub could be written as:
>
>     sub callback {
>         croak unless @_ == 2;
>         (my $self, $foo) = @_;
>         ...
>     }
>
> How would the caller (say an event handler module), which has been upgraded
> to pass an optional next arg, know that the callback sub it wanted to call
> would croak on that extra arg?
>

In this case it is self-inflicted. The person supplying the sub into the
framework broke the framework and gets to keep the pieces. The *framework*
owner isnt breaking the *callers* code, the caller is doing itself by
adding a constraint the framework author didnt ask for.

But in the signature case the framework author ends up in a trap, the only
way they can deal with this is change the api, eg, maybe the original code
had

$obj->new(callback=>$sub);

now they add a new argument and have to support:

$obj->new(callback=>$sub);
$obj->new(callback_2arg => $sub);

that starts getting ugly. If they could introspect on the artity of the sub
then this wouldnt be an issue at all. And everything would work fine.


>
> I think in the past that strong opinions have been expressed against
> allowing a signature API which a caller can use to inspect a sub, on the
> grounds that really the sub signature is an implementation detail - just a
> fancy and fast way of writing a @_ unpacker, and in general, doesn't form
> a promised API.
>

I think the case explained in the previous thread renders this argument
somewhat religious and not necessary and certainly not practical. If perl
itself  can complain and check the artity then it can expose a function to
do the same.

cheers,
Yves

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