Sigil & is not commonly used with function calls in modern Perl for two reasons. Firstly, this is pretty much redundant, as Perl will look at everything that looks like a function (followed by parens). Secondly, there is a big difference between the way &function() and &function are executed, which may confuse less experienced Perl programmers. In the first case, the function is called without arguments. In the second case, the function is called with the current @_ (and can even make changes to the list of arguments, which will be visible by later operations in this area:
sub print_and_remove_first_arg {print 'first arg: ', shift, "\n"} sub test { &print_and_remove_first_arg; print "remaining args: @_\n"; } test 1, 2, 3;
prints
first arg: 1 remaining args: 2 3
Thus, ultimately, using & for each function call ends up hiding several calls to &function; , which can lead to difficulty finding errors. In addition, using a cigar & prevents prototyping of functions that may be useful in some cases (if you know what you are doing), but can also lead to complex error tracking. Ultimately, & is a powerful behavior modifier and should only be used when it is needed.
Prototypes are similar, and their use should be limited in modern Perl. What should be stated explicitly is that prototypes in Perl are not function signatures. They are hints for the compiler that tell it to parse calls to these functions in a similar way to built-in functions. That is, each of the characters in the prototype tells the compiler to impose this type of context on the argument. This function can be very useful when defining functions that behave like map or push or keys , which all handle their first argument differently from the standard list operator.
sub my_map (&@) {...}
The reason sub ($$) {...} and similar prototypes are discouraged is because 9 times out of 10 the author means "I want two arguments" and not "I want two arguments each with a scalar context overlaid on the site call. " The first statement is better written:
use Carp; sub needs2 { @_ == 2 or croak 'needs2 takes 2 arguments'; ... }
which will then allow you to use the following call style as expected:
my @array = (2, 4); needs2 @array;
To summarize, sigil and function & prototypes are useful and powerful tools, but they should only be used when this functionality is required. Excessive use (or misuse as an argument) leads to inadvertent behavior and makes it difficult to track errors.