From: Gyepi SAM <[email protected]>
   Date: Wed, 10 Apr 2013 13:54:06 -0400

   On Tue, Apr 09, 2013 at 10:24:45PM -0400, Bob Rogers wrote:
   > 
   > Not quite true, as you can "goto" a label outside of the block:

   > [first example omitted]

   Indeed, you are correct. However, when you break out of a map in this
   way, the map returns an empty list, regardless of how many results
   had been previously collected.

Actually, the map does not return at all, as the following variation
shows:

    sub find_odd {
        my (@values) = @_;

        my $result;
        my @results = qw(nothing);
        @results = map { $result = $_ and goto LAST
                             if $_ & 1;
                         $_;
        } @values;
      LAST:
        warn "got ", join(' ', @results);
        return $result;
    }

You will see a "got nothing" warning when @values has an odd number, so
that the "goto" is taken.  In that case, "map" never returns, and the
assignment to @results is never made.

   Because your example handles a single result, it is not clear that,
   in fact, any return values MUST be collected similarly. Unless, of
   course, map is used simply for side effects.

I would hope (but don't know how to check) that Perl is smart enough to
notice that the "map" in my original example is in a void context, and
won't bother to store any return values from the block.  Is that what
you mean?

   > It's hard to think of a case where this would be better than a simple
   > loop, which is both smaller and more readable.  However, this technique
   > also gives you an early exit when mapping over a tree recursively.

   Even then, the need to handle collected values manually would seem to
   obviate any advantage in doing so.

Over the years, I have seen many applications for mapping over trees
(and also written a few), and most of them just produce side effects,
either to the tree or externally.  Those that don't tend to be of the
nature "collect (or count) all nodes that satisfy X," for which a
non-local exit would defeat the purpose.  Those that do require
non-local exit are of the form "find the *first* X" or "return true if
*any* X," where the burden of handling a scalar return is minimal and
the benefit from being able to skip the remainder of the tree is clear.

   In other words, I believe the "collect values" cases and the
"nonlocal exit" cases are effectively disjoint.  I've never found the
need for (e.g.) a "collect the first N nodes that satisfy X" routine.

   This discussion has confirmed, for me, that writing code is, in many
   ways, similar to writing prose. Though there may initially, appear to
   be many ways to communicate, thoughtfulness, good taste and
   circumstance quickly show that there are only a few good ways to do
   so.

   -Gyepi 

To the extent that there are vastly more ways to write bad (code|prose)
than good, I heartily agree.  But I submit that that still leaves an
enormous field of possibilities.  Of course, I always try to write the
best (code|prose) I can, subject to constraints, of course, and it often
seems to me that there's only a few acceptable solutions, maybe only
one.  But I have strong preferences in coding style, so I suspect that's
just my biases showing.

   Sorry to come back at you with so much disagreement; that was not my
intention.

                                        -- Bob

_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to