Why does Perl allow pass arguments by reference? - perl

I'm wondering why Perl has ability to pass argument by reference to function?
I know that neither Python, nor Ruby doesn't have such feature.

It's useful to distinguish one thing from another.
(1) Passing arguments to a subroutine by reference. This is useful in Perl because the language passes all arguments to a subroutine as an undifferentiated list of values. Without the ability to passed data structures by reference, the designer of a function taking two lists, for example, would not be able to keep the lists separate. In addition, if the data structures are large, passing them by reference can provide a performance gain.
process_two_lists( #x, #y); # Can't distinguish the lists.
process_two_lists(\#x, \#y); # Can.
Because Python and Ruby are designed differently, they don't require this distinction in how arguments are passed. A similar method in Python or Ruby would receive two distinct arguments (two objects representing lists x and y).
(2) Perl's behavior whereby #_ serves as an alias to the passed arguments, allowing the subroutine to modify data as perceived by the caller.
sub add_ten_to_me {
$_[0] += 10;
}
my $x = 1;
add_ten_to_me($x);
say $x; # 11 Amazing!
Python and Ruby can do this type of thing as well; however, there are some qualifications. Python distinguishes between mutable and immutable objects. If you pass something mutable to a Python method (a list, for example), the method is able to modify the data structure. So a Python version of process_two_lists would be able to modify both x and y. However, a function receiving immutable objects (an integer, for example) would not. Thus, a direct Python analog of add_ten_to_me would not work. [I believe that similar points could be made about Ruby, but I'm less familiar with the details at this point.]

Passing arguments by reference can give significant performance improvements.

Perl gives you the choice. I think it's part of that TIMTOWTDI idea. It's a flexible method, so you can do what you need. If you access the argument as $_[0] then it's the same object. If you shift it or copy it to a lexical, it's by value.
So think of it this way. Most code is by value, but by reference is there when you need it.

Related

What is the significance of ";" when defining formal parameters for a perl subroutine?

Background
When specifying formal parameters for a subroutine in perl, I am aware of the following notation. I'm not sure entirely what they mean, but form context clues and seeing other's explain their code, I have deduced this much:
sub method1($$){...} <-- Means it takes in two scalar parameters
sub method2(#){...} <-- Means it takes in a bunch of parameters as a hash
sub method3($#){...} <-- Menas it takes in a scalar parameter, then a bunch of other parameters as a hash.
However, I have also found this notation and am unaware of what it means:
sub method4(#;$)
Question
What, functionally, does the formal parameter declaration of #;$ do that #$ does not?
This feature is called prototypes, and it is not a formal parameter specification, but instead a ruleset for the parser of how to parse arguments passed to your subroutine, which also happens to do some rudimentary arity checking and coercion (sometimes in ways that will be surprising to the user). It is explained in that feature's documentation:
A semicolon (;) separates mandatory arguments from optional arguments. It is redundant before # or %, which gobble up everything else.
It is often simpler to not use prototypes at all than risk the confusion that they can cause. Some examples: a $ parameter will be forced into scalar context even if it is an array, and the prototype is ignored entirely when the subroutine is called as an object or class method (because it is not yet determined what subroutine will be called at the time the call is parsed).
For formal parameter specifications, use the signatures feature, or Function::Parameters (which currently has the benefit of being feature-complete - more features for signatures are coming soon).

What does the dollar character in the brackets of a Perl subroutine mean?

I've inherited some Perl code and occasionally I see subroutines defined like this:
sub do_it($) {
...
}
I can't find the docs that explain this. What does the dollar symbol in brackets mean?
It is a subroutine prototype.
The single $ means that the sub will only accept a single scalar value, and will interpret other types using scalar context. For instance, if you pass an array as the param e.g. do_it(#array), Perl will not expand #array into a list, but instead pass in the length of the array to the subroutine body.
This is sometimes useful as Perl can give an error message when the subroutine is called incorrectly. Also, Perl's interpreter can use the prototypes to disambiguate method calls. I have seen the & symbol (for code block prototype) used quite neatly to write native-looking routines that call to anonymous code.
However, it only works in some situations - e.g. it doesn't work very well in OO Perl. Hence its use is a bit patchy. Perl Best Practices recommends against using them.
The ($) is called a subroutine prototype.
See the PerlSub man page for more information: http://perldoc.perl.org/perlsub.html#Prototypes
Prototyping isn't very common nowadays. Best Practice is not using it.

Is using prototypes to declare array reference context on subroutine args a Good Thing in Perl?

In the linked SO answer, Eric illustrates a way to call a subroutine, which accepts arrays by reference as arguments, and use the prototypes to allow the caller code to pass the array names without using reference operator \#; the way built-ins like push #array, $value do.
# Original code:
sub Hello { my ($x_ref, $y_ref) = #_; ...}
Hello(\#x, \#y);
# Same thing using array ref prototype:
sub Hello (\#\#$) {...}
Hello(#x, #y);
My question is, is this considered to be a Best Practice? And what are the guidelines on the pattern's use?
It seems like this pattern should either be used ONLY for built-ins, or for 100% of subroutines that accept array arguments in all of your code.
Otherwise code maintenance and use of your subs becomes fragile since the developer never knows whether a particular sub, when called, should be forced to reference an array or not.
An additional point of fragility is that you become confused between doing such calls and legitimately using two arrays combined into one using a comma operator.
On the positive side, using the pattern prevents the "forgot to reference the array" bugs, and makes the code calling the subroutines somewhat more readable.
P.S. I don't have Conway's book handy and don't recall if he ever discussed the topic, to pre-empt RTFB responses.
Only use prototypes when you're trying to extend Perl's syntax: e.g. if you're building Moose, or something like the examples in Dominus' Higher Order Perl. If you're doing that, you know enough to disregard PBP (and to annotate your code to shut Perl::Critic up). If you're doing anything else, don't use them.
Let's ask Perl::Critic:
echo "use strict; sub Hello (\#\#$) {...}" | perlcritic
Subroutine prototypes used at line 1, column 1. See page 194 of PBP. (Severity: 5)
Yeah, that would be a no.
I tend to think that anything that makes a subroutine act differently than any other subroutine isn't the best thing. There might be instances where it's a good idea, but in general it's more special cases, documentation, and other things to remember. The more your code acts like most other Perl code, the easier you make things for your users.
Notice that this isn't the main complaint that Perl Best Practices has with prototypes, which is an ugly kludge in Perl.

Origin of discouraged perl idioms: &x(...) and sub x($$) { ... }

In my perl code I've previously used the following two styles of writing which I've later found are being discouraged in modern perl:
# Style #1: Using & before calling a user-defined subroutine
&name_of_subroutine($something, $something_else);
# Style #2: Using ($$) to show the number of arguments in a user-defined sub
sub name_of_subroutine($$) {
# the body of a subroutine taking two arguments.
}
Since learning that those styles are not recommended I've simply stopped using them.
However, out of curiosity I'd like to know the following:
What is the origin of those two styles of writing? (I'm sure I've not dreamt up the styles myself.)
Why are those two styles of writing discouraged in modern perl?
Have the styles been considered best practice at some point in time?
The & sigil is not commonly used with function calls in modern Perl for two reasons. First, it is largely redundant since Perl will consider anything that looks like a function (followed by parens) a function. Secondly, there is a major difference between the way &function() and &function are executed, which may be confusing to less experienced Perl programmers. In the first case, the function is called with no arguments. In the second case, the function is called with the current #_ (and it can even make changes to the argument list which will be seen by later statements in that scope:
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
So ultimately, using & for every function call ends up hiding the few &function; calls which can lead to hard to find bugs. In addition, using the & sigil prevents the honoring of function prototypes, which can be useful in some cases (if you know what you are doing), but also may lead to hard to track down bugs. Ultimately, & is a powerful modifier to function behavior, and should only be used when that behavior is desired.
Prototypes are similar, and their use should be limited in modern Perl. What must be stated explicitly is that prototypes in Perl are NOT function signatures. They are hints to the compiler that tell it to parse calls to those functions in a similar way as the built in functions. That is, each of the symbols in the prototype tells the compiler to impose that type of context on the argument. This functionality can be very helpful when defining functions that behave like map or push or keys which all treat their first argument differently than a standard list operator would.
sub my_map (&#) {...} # first arg is either a block or explicit code reference
my #ret = my_map {some_function($_)} 1 .. 10;
The reason sub ($$) {...} and similar uses of prototypes are discouraged is because 9 times out of 10 the author means "I want two args" and not "I want two args each with scalar context imposed on the call site". The former assertion is better written:
use Carp;
sub needs2 {
#_ == 2 or croak 'needs2 takes 2 arguments';
...
}
which would then allow the following calling style to work as expected:
my #array = (2, 4);
needs2 #array;
To sum up, both the & sigil and function prototypes are useful and powerful tools, but they should only be used when that functionality is required. Their superfluous use (or misuse as argument validation) leads to unintended behavior and difficult to track down bugs.
The & in function-calls was mandatory in Perl 4, so maybe you have picked that up from Programming perl (1991) by Larry Wall and Randal L. Schwartz, as I did, or somewhere similar.
As for the function prototypes, my guess is less qualified. Maybe you have been mimicking languages where it makes sense and/or is mandatory to declare argument lists, and since function prototypes in Perl look a little like argument lists, you've started adding them?
&function is discouraged because it makes the code less readable and isn't necessary (the cases that &function is necessary are rare and often better avoided).
Function prototypes aren't argument lists, so most of the time they'll just confuse your reader or lull you into a false sense of rigidity, so no need to use those unless you know exactly why you are.
& was mandatory in Perl 4, so they have been best/necessary practise. I don't think function prototypes ever has been.
For style #1, the & before the subroutine is only necessary if you have a subroutine that shares a name with a builtin and you need to disambiguate which one you wish to call, so that the interpreter knows what's going on. Otherwise, it's equivalent to calling the subroutine without &.
Since that's the case, I'd say its use is discouraged since you shouldn't be naming your subroutines with the same names as builtins, and it's good practice to define all your subroutines before you call them, for the sake of reading comprehension. In addition to this, if you define your subroutines before you call them, you can omit the parentheses, like in a builtin. Plus, just speaking visually, sticking & in front of every subroutine unnecessarily clutters up the file.
As for function prototypes, they were stuck into Perl after the fact and don't really do what they were made to do. From an article on perl.com:
For the most part, prototypes are more trouble than they're worth. For one thing, Perl doesn't check prototypes for methods because that would require the ability to determine, at compile time, which class will handle the method. Because you can alter #ISA at runtime--you see the problem. The main reason, however, is that prototypes aren't very smart. If you specify sub foo ($$$), you cannot pass it an array of three scalars (this is the problem with vec()). Instead, you have to say foo( $x[0], $x[1], $x[2] ), and that's just a pain.
In the end, it's better to comment your code to indicate what you intend for a subroutine to accept and do parameter checking yourself. As the article states, this is actually necessary for class methods, since no parameter checking occurs for them.
For what it's worth, Perl 6 adds formal parameter lists to the language like this:
sub do_something(Str $thing, Int $other) {
...
}

When should I use the & to call a Perl subroutine?

I have heard that people shouldn't be using & to call Perl subs, i.e:
function($a,$b,...);
# opposed to
&function($a,$b,...);
I know for one the argument list becomes optional, but what are some cases where it is appropriate to use the & and the cases where you should absolutely not be using it?
Also how does the performace increase come into play here when omitting the &?
I'm a frequent abuser of &, but mostly because I'm doing weird interface stuff. If you don't need one of these situations, don't use the &. Most of these are just to access a subroutine definition, not call a subroutine. It's all in perlsub.
Taking a reference to a named subroutine. This is probably the only common situation for most Perlers:
my $sub = \&foo;
Similarly, assigning to a typeglob, which allows you to call the subroutine with a different name:
*bar = \&foo;
Checking that a subroutine is defined, as you might in test suites:
if( defined &foo ) { ... }
Removing a subroutine definition, which shouldn't be common:
undef &foo;
Providing a dispatcher subroutine whose only job is to choose the right subroutine to call. This is the only situation I use & to call a subroutine, and when I expect to call the dispatcher many, many times and need to squeeze a little performance out of the operation:
sub figure_it_out_for_me {
# all of these re-use the current #_
if( ...some condition... ) { &foo }
elsif( ...some other... ) { &bar }
else { &default }
}
To jump into another subroutine using the current argument stack (and replacing the current subroutine in the call stack), an unrare operation in dispatching, especially in AUTOLOAD:
goto ⊂
Call a subroutine that you've named after a Perl built-in. The & always gives you the user-defined one. That's why we teach it in Learning Perl. You don't really want to do that normally, but it's one of the features of &.
There are some places where you could use them, but there are better ways:
To call a subroutine with the same name as a Perl built-in. Just don't have subroutines with the same name as a Perl built-in. Check perlfunc to see the list of built-in names you shouldn't use.
To disable prototypes. If you don't know what that means or why you'd want it, don't use the &. Some black magic code might need it, but in those cases you probably know what you are doing.
To dereference and execute a subroutine reference. Just use the -> notation.
IMO, the only time there's any reason to use & is if you're obtaining or calling a coderef, like:
sub foo() {
print "hi\n";
}
my $x = \&foo;
&$x();
The main time that you can use it that you absolutely shouldn't in most circumstances is when calling a sub that has a prototype that specifies any non-default call behavior. What I mean by this is that some prototypes allow reinterpretation of the argument list, for example converting #array and %hash specifications to references. So the sub will be expecting those reinterpretations to have occurred, and unless you go to whatever lengths are necessary to mimic them by hand, the sub will get inputs wildly different from those it expects.
I think mainly people are trying to tell you that you're still writing in Perl 4 style, and we have a much cleaner, nicer thing called Perl 5 now.
Regarding performance, there are various ways that Perl optimizes sub calls which & defeats, with one of the main ones being inlining of constants.
There is also one circumstance where using & provides a performance benefit: if you're forwarding a sub call with foo(#_). Using &foo is infinitesimally faster than foo(#_). I wouldn't recommend it unless you've definitively found by profiling that you need that micro-optimization.
The &subroutine() form disables prototype checking. This may or may not be what you want.
http://www.perl.com/doc/manual/html/pod/perlsub.html#Prototypes
Prototypes allow you to specify the numbers and types of your subroutine arguments, and have them checked at compile time. This can provide useful diagnostic assistance.
Prototypes don't apply to method calls, or calls made in the old-fashioned style using the & prefix.
The & is necessary to reference or dereference a subroutine or code reference
e.g.
sub foo {
# a subroutine
}
my $subref = \&foo; # take a reference to the subroutine
&$subref(#args); # make a subroutine call using the reference.
my $anon_func = sub { ... }; # anonymous code reference
&$anon_func(); # called like this
Protypes aren't applicable to subroutine references either.
The &subroutine form is also used in the so-called magic goto form.
The expression goto &subroutine replaces the current calling context with a call to the named subroutine, using the current value of #_.
In essence, you can completely switch a call to one subroutine with a call to the named one. This is commonly seen in AUTOLOAD blocks, where a deferred subroutine call can be made, perhaps with some modification to #_ , but it looks to the program entirely as if it was a call to the named sub.
e.g.
sub AUTOLOAD {
...
push #_, #extra_args; # add more arguments onto the parameter list
goto &subroutine ; # change call another subroutine, as if we were never here
}
}
Potentially this could be useful for tail call elimination, I suppose.
see detailed explanation of this technique here
I've read the arguments against using '&', but I nearly always use it. It saves me too much time not to. I spend a very large fraction of my Perl coding time looking for what parts of the code call a particular function. With a leading &, I can search and find them instantly. Without a leading &, I get the function definition, comments, and debug statements, usually tripling the amount of code I have to inspect to find what I'm looking for.
The main thing not using '&' buys you is it lets you use function prototypes. But Perl function prototypes may create errors as often as they prevent them, because they will take your argument list and reinterpret it in ways you might not expect, so that your function call no longer passes the arguments that it literally says it does.