http://qs1969.pair.com?node_id=862277


in reply to Far More than Everything You've Ever Wanted to Know about Prototypes in Perl -- by Tom Christiansen

I still like prototypes and wish they could be enforced (or generate a warning) at runtime, when used incorrectly, indirectly. I see that as the biggest limitation of the current implementation of 'parsing prototypes' -- that they are only enforced or only used during direct calls.

Everything else that the author complained about was a non-complaint *if* you follow the 1st 'best practice' (In my book) of turning on "-w" at the start.

All of the multi-prototypes like he shows would generate warnings. The only prototype 'gotcha', that really exists with the current prototype system -- that *could* be improved upon, with a language extension, is the situation of declaring a proto with sub foobar($); and then calling it with foo(@a) and expecting that to throw an error rather than evaluating the array in scalar context.

An additional warning could be added with some additional warning level (Warn-pedantic), to warn of implicit type conversions where a prototype was involved. You couldn't reasonably warn of implicit type conversions everywhere without alot of code rewrite, so turning on warning only for explicitly prototyped functions might be a reasonable 'by-request' addition to warnings.

Ideally, one might add an explicit type-cast operator syntax -- an extension of the 'wantarray' "question" operator -- where instead of just asking if an array is wanted in the return context, have some variation of wantarray that forces array interpretation instead of scalar.

I ran into a desire for this recently, where I had an array reference in a variable, but when I tried to use it with some operator that expected an array, it wouldn't work -- only by assigning it to an array first, would it work as I needed it to. But more important would be the ability to say 'want type (X)', before a var -- that way if one DID have warnings for prototypes that do implicit conversions, one could add the typecast to make the conversion explicit and eliminate the warning, like:

sub foobar($); foobar(($)@arr);
meaning a syntax that explicitly uses '@arr' in a scalar context so IF a warning for 'implicit conversions' with explicitly prototyped functions doing an implicit conversion was enabled, the warning could be silenced.

Similarly a warning could be made 'available' for assigning diverse types to a data structure or variable -- something that currently is allowed with no warning (it's a feature!) within a variable's scope -- like:

use warnings '+mixedtypes'; @a=(1,2); @b=(@a, [3,4]); #would give warning!
That would require clarification of lines like the assignment to @b. Did they really want @b to contain 3 elements, 2 scalars and a reference, or did they want @b to contain 2 references? Or inconsistent usages like:
use warnings '+mixedtypes'; @a=(1,2); $a[1]=[3,4]; #warning - mixed type assigned to @a $a[1]=($)[3,4]; #would store the ref into a scalar-typed target witho +ut warning
The would certainly be for use with a particular type of coding practice, but one that would allow for only strictly typed-check usage.

Maybe it's not practical for some reason, but if it were, I could see it being useful for a more careful, more verbose style of programming -- perhaps it's already been done in some module?

Replies are listed 'Best First'.
Re^2: Far More than Everything You've Ever Wanted to Know about Prototypes in Perl -- by Tom Christiansen
by Crackers2 (Parson) on Oct 01, 2010 at 23:33 UTC
    the situation of declaring a proto with sub foobar($); and then calling it with foo(@a) and expecting that to throw an error rather than evaluating the array in scalar context.

    I'd argue that the more common expectation is that this should just use the first element of @a, which is what would happen if there was no prototype.

    Which is what I've seen often quoted as the biggest problem with perl prototypes; instead of enforcing subroutine arguments, it changes the way arguments are parsed.