develooper Front page | perl.perl5.porters | Postings from November 2016

Re: RFC: core sub signature introspection

Thread Previous | Thread Next
November 25, 2016 06:43
Re: RFC: core sub signature introspection
Message ID:
Sam Kington wrote:
>Now, the iterate sub here is merely saying "if you pass me a coderef,
>it must have a subroutine signature so I know what to pass to it". I
>think that's not unreasonable,

The unreasonableness is that it means that whether a sub is written
using a signature, and what the arity of that signature is, becomes a
public feature on which users rely.  They rely on it when they pass the
sub to iterate() which has this requirement.  They require that the sub
contains a signature, and that the arity of that signature (whichever
arity iterate() looks at) be the correct arity for the structure of the
argument array that they supply to iterate().  That means that changing
these parts of the sub's implementation would break those users, so the
author can't acceptably do that.

Thus, having once used a signature, the sub's author is constrained to
*always* implement it with a signature in all future versions, and to
never change whichever aspect of its arity iterate() looks at.  So the sub
can't ever be reimplemented in XS, and the calling convention can't ever
be extended to make a formerly-mandatory parameter optional.  These are
types of change that are reasonably normal to make between module
versions, and which currently don't cause any compatibility problem.

>Assuming that the calling code does indeed depend on said module being
>around, and that module has indeed changed its public API so dramatically,
>and the calling code can't mandate a known-good version, it has to
>maintain its own lookup table of "version 1 expects two parameters,
>version 2 expects three parameters"

Yes, in that kind of situation of incompatible change the caller does
indeed need to know how to handle each calling convention that it
might have to deal with.  This is an aspect of the situation that your
previous comments missed: if the caller doesn't specifically know about
each calling convention, then knowing how many arguments are expected
doesn't help.  If I have a key/value list that I'm expecting to pass to
the function two at a time, perhaps through arc's iterate(), and the new
version that I don't specifically know about demands three arguments (say,
key/value/encoding), then I'm out of luck.  Rebracketing the list into
key/value/key and value/key/value tuples, as iterate() would, won't help.

To deal with these incompatible API changes, the caller needs to recognise
which API it must use, and in general invoke different code accordingly.
Querying arity would in some cases be a way to achieve the former, but
it would be just as easy to check the module's $VERSION, so that's not
really gaining anything there.  It's also somewhat more likely that the
incompatible change wouldn't be to the number of parameters taken by a
sub, but in the meaning of the parameters, meaning of the returned value,
or some other aspect of the module API.  Querying arity doesn't help at
all in those cases, but a $VERSION check works just fine.

So really, arity introspection doesn't help with any part of dealing
with incompatible API changes.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About