Use of "return" in place of "last" (newbie question)?

Discussion in 'Perl Misc' started by Michael, Mar 9, 2008.

  1. Michael

    Michael Guest

    I am new to perl, and I am wondering whether it is a bad thing to jump out
    of a foreach loop with return. I have a function which searches for a
    value in one of several arrays. If the value is found in any of them,
    then the whole function may as well terminate. At the moment I am setting
    a flag when the value is found, which stops execution of the later loops.
    Would it be safe / stylistically sound to do away with the flag by using
    "return" rather than "last". Example code follows.

    TIA

    sub example{

    my $found;
    $found = 0;

    foreach $item (@list)
    {
    if ($value eq $item)
    {
    print ("found $value\n");
    $found = 1;
    last;
    }
    }

    .... several other foreach loops follow in which the only thing which
    differs is the name of the array which is "@list" above, and the test for
    the flag.

    return
    }
     
    Michael, Mar 9, 2008
    #1
    1. Advertising

  2. Michael <> wrote:

    > I am new to perl, and I am wondering whether it is a bad thing to jump out
    > of a foreach loop with return.



    Yes it is a bad thing, because it will not work. :)


    > I have a function which searches for a
    > value in one of several arrays. If the value is found in any of them,
    > then the whole function may as well terminate.



    Oh.

    Using a return() to return from a subroutine is perfectly fine
    (even if the return() is within a loop).


    > Would it be safe / stylistically sound to do away with the flag by using
    > "return" rather than "last".



    Yes.


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad J McClellan, Mar 9, 2008
    #2
    1. Advertising

  3. Michael

    Michael Guest

    On Sun, 09 Mar 2008 10:16:08 -0500, Tad J McClellan wrote:
    <snip>
    >
    > Using a return() to return from a subroutine is perfectly fine (even if
    > the return() is within a loop).
    >
    >> Would it be safe / stylistically sound to do away with the flag by
    >> using "return" rather than "last".

    >
    > Yes.


    Many thanks for the prompt and helpful response Tad.

    /M
     
    Michael, Mar 9, 2008
    #3
  4. Michael <> wrote:
    >I am new to perl, and I am wondering whether it is a bad thing to jump out
    >of a foreach loop with return.


    Technically it doesn't make a difference.

    Stylistically it is a matter of which programming philosophy you are
    following. For GOTOists it is standard operating procedure, for functional
    programmers it is a sacrilege. Others are somewhere in between.

    jue
     
    Jürgen Exner, Mar 9, 2008
    #4
  5. Jürgen Exner <> writes:

    > Michael <> wrote:
    >>I am new to perl, and I am wondering whether it is a bad thing to jump out
    >>of a foreach loop with return.

    >
    > Technically it doesn't make a difference.
    >
    > Stylistically it is a matter of which programming philosophy you are
    > following. For GOTOists it is standard operating procedure, for functional
    > programmers it is a sacrilege. Others are somewhere in between.


    Functional programmers don't use foreach either :)

    Personally, I think using a return statement generally leads to less
    convoluted, clearer code.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 9, 2008
    #5
  6. Michael

    Michael Guest

    On Sun, 09 Mar 2008 17:14:19 +0000, Jürgen Exner wrote:

    > Michael <> wrote:
    >>I am new to perl, and I am wondering whether it is a bad thing to jump
    >>out of a foreach loop with return.

    >
    > Technically it doesn't make a difference.
    >
    > Stylistically it is a matter of which programming philosophy you are
    > following. For GOTOists it is standard operating procedure, for
    > functional programmers it is a sacrilege. Others are somewhere in
    > between.


    Thank-you.

    Just as a matter of interest, so far as I could see, my technique of
    setting a flag was the simplest way of maintaining the integrity of the
    foreach (terminating it with "last" rather than jumping out of it with
    "return"), whilst not wasting processor cycles performing irrelevant loops
    later in the function. I am a newbie and don't know much - is there a
    more elegant alternative which would satisfy the functional programmers?
     
    Michael, Mar 9, 2008
    #6
  7. Michael <> writes:

    > On Sun, 09 Mar 2008 17:14:19 +0000, Jürgen Exner wrote:
    >
    >> Michael <> wrote:
    >>>I am new to perl, and I am wondering whether it is a bad thing to jump
    >>>out of a foreach loop with return.

    >>
    >> Technically it doesn't make a difference.
    >>
    >> Stylistically it is a matter of which programming philosophy you are
    >> following. For GOTOists it is standard operating procedure, for
    >> functional programmers it is a sacrilege. Others are somewhere in
    >> between.

    >
    > Thank-you.
    >
    > Just as a matter of interest, so far as I could see, my technique of
    > setting a flag was the simplest way of maintaining the integrity of the
    > foreach (terminating it with "last" rather than jumping out of it with
    > "return"), whilst not wasting processor cycles performing irrelevant loops
    > later in the function. I am a newbie and don't know much - is there a
    > more elegant alternative which would satisfy the functional programmers?


    There are more "elegant" (for some value of elegant) functional
    alternatives , but perl's constructs don't really allow you to write
    them as nicely as more functional programming languages do. For one,
    perl's if { ... } else { ... } constructs aren't expressions, and also,
    perl uses arrays instead of linked lists:

    example in common lisp

    (defun find-value (value list)
    (and list
    (if (string= value (first list))
    value
    (find-value (rest list)))))

    (defun example
    (or (find-value my-value my-list)
    (find-value my-other-value my-other-list)))

    Using these kind of recursive calls almost automatically
    force you to break up your sample problem into 2 subs.

    Also note that you can then re-use the find-value sub to reduce the
    total amount of code.


    same algorithm in perl.

    sub find_value {
    my ($value,@list) = @_;
    if (@list) {
    my $first = shift @list;
    if ($first eq $value) {
    return $first;
    }
    return find_value($value,@list);
    }
    return; # return false
    }

    sub example {
    find_value($value,@list) or
    find_value($other_value,@other_list);
    }

    note that you probably still want to use plenty of return()s
    here.

    also note: is is pretty inefficient if @list is long. you'd
    generally write the find_value function using foreach(), and pass
    the lists as array references.

    ps: none of this code has been tested. YMMV.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
     
    Joost Diepenmaat, Mar 9, 2008
    #7
  8. Michael <> wrote:
    >On Sun, 09 Mar 2008 17:14:19 +0000, Jürgen Exner wrote:
    >
    >> Michael <> wrote:
    >>>I am new to perl, and I am wondering whether it is a bad thing to jump
    >>>out of a foreach loop with return.

    >>
    >> Technically it doesn't make a difference.
    >>
    >> Stylistically it is a matter of which programming philosophy you are
    >> following. For GOTOists it is standard operating procedure, for
    >> functional programmers it is a sacrilege. Others are somewhere in
    >> between.


    >Just as a matter of interest, so far as I could see, my technique of
    >setting a flag was the simplest way of maintaining the integrity of the
    >foreach (terminating it with "last" rather than jumping out of it with
    >"return"), whilst not wasting processor cycles performing irrelevant loops
    >later in the function. I am a newbie and don't know much - is there a
    >more elegant alternative which would satisfy the functional programmers?


    Well, doing strict functional programming in Perl is extremely hard anyway
    because that't not how the language was designed.
    But if you follow structured programming/formal programming/program
    transformations/... then the condition under which the loop terminiates
    should be defined in the condition of the loop. Neither last() nor return()
    fits that bill because they exit the loop unexpectedly from somewhere in the
    middle which is a nightmare for e.g. formal program verification.

    Using tons of flags is the typical workaround by inexperienced programmers.
    I have seen that literally hundreds of times in our university classes.
    Unfortunately flags can easily lead to to convoluted and difficult to
    maintain code because it can become very difficult to follow their logic and
    to analyse where which flag is being set under what conditions.

    Very often it takes just a little bit of restructuring of the loop to get a
    clean and easy to understand single exit condition without bail-outs in the
    middle. One approach that works often is to rearrange the exection sequence
    in the loop and/or reduce the loop by one iteration by moving some
    initialization code before the loop:

    Generic example:
    while (cond_x) {
    do_some_work();
    if (cond_y) {last};
    do_more_work();
    }

    can usually be transformed into something like
    do__prep_work(); #includes do_some_work() for first iteration
    while (cond_x and not cond_y) {
    do_more_work();
    do_some_work();
    }

    jue



    IMO the better app
     
    Jürgen Exner, Mar 9, 2008
    #8
  9. Michael

    Michael Guest

    On Sun, 09 Mar 2008 19:49:41 +0000, Jürgen Exner wrote:
    <snip>
    >>Just as a matter of interest, so far as I could see, my technique of
    >>setting a flag was the simplest way of maintaining the integrity of the
    >>foreach (terminating it with "last" rather than jumping out of it with
    >>"return"), whilst not wasting processor cycles performing irrelevant
    >>loops later in the function. I am a newbie and don't know much - is
    >>there a more elegant alternative which would satisfy the functional
    >>programmers?

    >
    > Well, doing strict functional programming in Perl is extremely hard
    > anyway because that't not how the language was designed. But if you
    > follow structured programming/formal programming/program
    > transformations/... then the condition under which the loop terminiates
    > should be defined in the condition of the loop. Neither last() nor
    > return() fits that bill because they exit the loop unexpectedly from
    > somewhere in the middle which is a nightmare for e.g. formal program
    > verification.
    >
    > Using tons of flags is the typical workaround by inexperienced
    > programmers. I have seen that literally hundreds of times in our
    > university classes. Unfortunately flags can easily lead to to convoluted
    > and difficult to maintain code because it can become very difficult to
    > follow their logic and to analyse where which flag is being set under
    > what conditions.
    >
    > Very often it takes just a little bit of restructuring of the loop to
    > get a clean and easy to understand single exit condition without
    > bail-outs in the middle. One approach that works often is to rearrange
    > the exection sequence in the loop and/or reduce the loop by one
    > iteration by moving some initialization code before the loop:
    >
    > Generic example:
    > while (cond_x) {
    > do_some_work();
    > if (cond_y) {last};
    > do_more_work();
    > }
    >
    > can usually be transformed into something like
    > do__prep_work(); #includes do_some_work() for first iteration while
    > (cond_x and not cond_y) {
    > do_more_work();
    > do_some_work();
    > }


    Thank-you very much for taking the time to write so helpfully Jue.

    /M
     
    Michael, Mar 9, 2008
    #9
  10. Michael

    Michael Guest

    On Sun, 09 Mar 2008 18:56:51 +0100, Joost Diepenmaat wrote:

    <snip>
    >> Just as a matter of interest, so far as I could see, my technique of
    >> setting a flag was the simplest way of maintaining the integrity of the
    >> foreach (terminating it with "last" rather than jumping out of it with
    >> "return"), whilst not wasting processor cycles performing irrelevant
    >> loops later in the function. I am a newbie and don't know much - is
    >> there a more elegant alternative which would satisfy the functional
    >> programmers?

    >
    > There are more "elegant" (for some value of elegant) functional
    > alternatives , but perl's constructs don't really allow you to write
    > them as nicely as more functional programming languages do. For one,
    > perl's if { ... } else { ... } constructs aren't expressions, and also,
    > perl uses arrays instead of linked lists:
    >
    > example in common lisp
    >
    > (defun find-value (value list)
    > (and list
    > (if (string= value (first list))
    > value
    > (find-value (rest list)))))
    >
    > (defun example
    > (or (find-value my-value my-list)
    > (find-value my-other-value my-other-list)))
    >
    > Using these kind of recursive calls almost automatically force you to
    > break up your sample problem into 2 subs.
    >
    > Also note that you can then re-use the find-value sub to reduce the
    > total amount of code.
    >
    >
    > same algorithm in perl.
    >
    > sub find_value {
    > my ($value,@list) = @_;
    > if (@list) {
    > my $first = shift @list;
    > if ($first eq $value) {
    > return $first;
    > }
    > return find_value($value,@list);
    > }
    > return; # return false
    > }
    >
    > sub example {
    > find_value($value,@list) or
    > find_value($other_value,@other_list);
    > }
    >
    > note that you probably still want to use plenty of return()s here.
    >
    > also note: is is pretty inefficient if @list is long. you'd generally
    > write the find_value function using foreach(), and pass the lists as
    > array references.
    >
    > ps: none of this code has been tested. YMMV.


    Thank-you very much for taking the time to write so helpfully Joost.

    /M
     
    Michael, Mar 9, 2008
    #10
  11. Michael

    Michael Guest

    On Sun, 09 Mar 2008 21:28:36 +0000, David Formosa (aka ? the Platypus)
    wrote:
    <snip>

    > You might look at the function "first" from the core module List::Util
    > which implements that for you.


    Thank-you. I had no idea that existed. Perl is a rather extensive
    wonderland.

    /M
     
    Michael, Mar 9, 2008
    #11
  12. Michael

    Ted Zlatanov Guest

    On Sun, 09 Mar 2008 17:30:49 +0000 Michael <> wrote:

    M> Just as a matter of interest, so far as I could see, my technique of
    M> setting a flag was the simplest way of maintaining the integrity of the
    M> foreach (terminating it with "last" rather than jumping out of it with
    M> "return"), whilst not wasting processor cycles performing irrelevant loops
    M> later in the function. I am a newbie and don't know much - is there a
    M> more elegant alternative which would satisfy the functional programmers?

    Don't worry about satisfying functional programmers or anyone else. Get
    the task done, write correct maintainable code, and that's enough.

    Ted
     
    Ted Zlatanov, Mar 10, 2008
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Carl
    Replies:
    21
    Views:
    1,029
    Patricia Shanahan
    Aug 24, 2006
  2. Greenhorn
    Replies:
    15
    Views:
    885
    Keith Thompson
    Mar 6, 2005
  3. sangram
    Replies:
    16
    Views:
    2,087
  4. Johny
    Replies:
    8
    Views:
    417
  5. jr
    Replies:
    6
    Views:
    333
Loading...

Share This Page