Yes examples 1 & 3 are much better. At some point signatures will be added to core Perl (class/method nearly made it into 5.16 as part of p5-mop proposal. Fingers crossed it will be in 5.18 next year).
When not using perl5i or playing with MooseX::Declare I will usually default to Params::Validate so your example would look like this:
sub function1 {
my ($code, $arr) = validate_pos( @_, {type => CODEREF}, {type => ARRAYREF} );
...
}
Example 1 (my work's internal source filter format):
Example 2 (standard Perl): Example 3 (Method::Signature):