Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I've got two problems with the whole thing that would prevent me from ever accepting it as a "common idiom".

First, the function has a side effect: It modifies its parameters. I understand, that's its primary purpose: to modify its parameters. But this isn't C++; Perl makes it so easy to pass complex return values that idiomatically, it's rare to see a Perl subroutine that intentionally modifies its parameter list (unlike C++, where it's a common idiom to pass objects by reference and manipulate them so that the side effect propagates back through the parameter list). This is why PBP encourages unpacking @_, not just because it looks prettier inside the subroutine, but because it reduces the potential of surprising someone who wasn't watching out for parameter side effects. Writing a Perl subroutine that modifies its parameters violates the principle of least surprise.

Second, as long as we're working so hard to modify the parameter list, let's make the following a fatal error:

swap( qw(this that) );

The first two versions don't throw an error when swap is called with static parameters. The third one does.

But they all have a return value of the swapped list, so they're useful even when modifying the parameter list isn't the goal, right? Well, sort of. All three swap functions produce a reasonable return value. As soon as you decide it's Ok to use the subroutine for its return value instead, and write something like this:

my @swapped = swap ( qw(this that) );

...which is fine for the first two examples, you're going to forget, and go ahead at some point using it like this:

my @swapped = swap( $variables_that_should, $not_be_swapped )

Not only would this idiom need a #comment whenever the subroutine is defined, it would need a comment whenever it's used reminding the reader that in one case we're intentionally modifying the parameters, or in another case we shouldn't use the parameters ever again because they just got modified even though we're capturing a return value.

Regardless of whether or not you happen to be Ok with subroutines that modify their parameter list, one that does it through an extra layer of indirection is even sneakier, and one layer harder to skim as someone reads through the code later on. Though I don't like any of them, at least the last one will throw an error if you attempt to swap literals, and at first glance looks like it does exactly what it does: It acts upon @_, which is an alias. If we ignore the advice of avoiding the pitfall of modifying the parameters, I believe it's a particularly bad practice to follow the PBP suggestion of unpacking the parameter list. It lulls the casual reader into a sense of false security. If PBP had a rule that permitted modifying the parameter list, it would (or should) say to do so in a visually unambiguous way.

(Think how many times we see this in a newbie's code: while( my line = <DATA> ) { my $result = chomp $line; ... } )


In reply to Re: RFC: Idiom for named read-write arguments (aliases) instead of using $_[0] etc by davido
in thread RFC: Idiom for named read-write arguments (aliases) instead of using $_[0] etc by LanX

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others examining the Monastery: (8)
    As of 2018-06-20 19:42 GMT
    Find Nodes?
      Voting Booth?
      Should cpanminus be part of the standard Perl release?

      Results (117 votes). Check out past polls.