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