Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Using & in function calls

by throop (Chaplain)
on Sep 28, 2007 at 22:47 UTC ( [id://641633]=perlquestion: print w/replies, xml ) Need Help??

throop has asked for the wisdom of the Perl Monks concerning the following question:

Brethren,

Perl Best Practices (p 176) deprecates using an & before function calls, i.e. it prefers

snafu();
instead of
&snafu;
But all of the examples seemed like places where already-bad coding was made worse by &; not real convincing. I continue to use the & because
  • EMACS displays &function; as &function; and the color contrast helps me navigate in the code
  • It's the way I learned to do it back in Perl 4; some of my code dates all the way back there, and I just keep a visual consistency to it all.
OK, the second reason is pretty lame, but the color-coding in EMACS is helpful.

I was surprised to learn today

Be warned that Perl does not check prototypes when a subroutine call includes the & prefix.
But that seems more like a reason not to use prototypes than not to use &

Outside aesthetics, are there compelling reasons not to use the &? Compelling enough to make me go back and clean-up my already-written code that uses them?

throop

Replies are listed 'Best First'.
Re: Using & in function calls
by Joost (Canon) on Sep 28, 2007 at 23:47 UTC
    As far as I'm concerned, there are two reasons to not use &:

    1. using &subname; without braces does not do what you probably think it does. It passes the current value of @_ to the called sub - and subname() update: or subname; does not.

    2. when you're passing arguments, most of the time the you are either using braces and/or the subroutine has already been defined, and in both cases the & is not needed. Also strict will warn you if it gets confused in this case. Basically, not using "&" will save you typing.

    The only times I use &subname is when a) I want to create a reference to a named subroutine (which is fairly rare), or b) I want to do goto &subname; (which is an even more rare, but does have its uses in that it's the only way to "fake tailrecursion" in perl - see goto)

      ... or b) I want to do goto &subname; (which is an even more rare, but does have its uses in that it's the only way to "fake tailrecursion" in perl - see goto)

      Actually thats not correct, it is neither the only nor the best way to "fake tailrecursion". The best way to fake tail recursion is to use a while or for loop. The overhead of goto &sub is actually quite expensive compared to a proper loop.

      Tail recursion optimisation is only really important in languages which lack looping constructs. Yet the meme that "tail recursion optimisation is cool and useful" somehow manages to leak out of languages that really do need it into languages that don't really need it. And Perl has a rich set of looping constructs making tail recursion and its optimisation much less important than people think. This is actually one of the reasons that perl doesnt bother with this optimisation. (Its not the only reason tho given Perls dynamic nature.)

      Remember that all tail recursion optimisation does is quietly convert your tail recursive call into a loop.

      ---
      $world=~s/war/peace/g

        Well, yes.

        But, it can be useful to have the called subroutine determine the next call instead of moving the determining code to the calling routine. And doing that "naively" will lead you running out of call stack if you have enough nested calls.

        I've used the goto &subroutine; construct to get out of that situation.

        I acknowledge that this isn't strictly tail recursion.

Re: Using & in function calls
by Sidhekin (Priest) on Sep 28, 2007 at 23:01 UTC

    &snafu, as you have it, without parentheses, is actually even more magical: It passes the current @_ toshares the current @_ with the function called. Which you rarely, if ever, want.

    (Updated: Yeah, that's better. lodin++.)

    The &snafu(@args), &snafu(), and &snafu forms are useful in very rare situations, and the & is a nice flag for just those instances: When I see it in my code, I know I'm doing something strange. Which is also useful.

    So yeah, not just aesthetics. Compelling enough? You make the call. But my recommendation for &-form calls is as for prototypes:

    Don't use it if you don't mean it!

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

      It passes the current @_ to the function called.

      This is probably just a matter of wording, but I'd say it's sharing @_. &foo and foo(@_) are not equivalent. An example:

      sub foo1 { &bar; print "@_\n"; } sub foo2 { bar(@_); print "@_\n"; } sub bar { shift } foo1(1, 2, 3); foo2(1, 2, 3); __END__ 2 3 1 2 3

      lodin

Re: Using & in function calls
by TimToady (Parson) on Sep 29, 2007 at 17:10 UTC
    Note also that & changes meaning slightly in Perl 6, where it's merely a noun marker. So &foo just names the foo routine without calling it. (And there's no magical @_ passing anymore.) To call foo you must either use it bare as a verb or explicitly dereference the noun with postfix parentheses.
Re: Using & in function calls
by FunkyMonk (Chancellor) on Sep 28, 2007 at 22:55 UTC
    The most compelling reason you should have for not using &func, is that you don't know what it does.

    Would you use system "rm -rf" or del \*.* in your code if you didn't know what they did?

    The fact that you had to ask this question tells me that you should not be using &func.

Re: Using & in function calls (classic)
by tye (Sage) on Sep 29, 2007 at 05:43 UTC
Re: Using & in function calls
by Porculus (Hermit) on Oct 03, 2007 at 17:41 UTC
    If you want to kick the habit, give cperl-mode a try instead of perl-mode; it doesn't seem to colour &foo;, and it does colour some other useful things, like regex metachars.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://641633]
Approved by Sidhekin
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2024-04-19 05:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found