RE: A goto-like usage of a function

Discussion in 'Python' started by Tim Golden, Jul 29, 2004.

  1. Tim Golden

    Tim Golden Guest

    [Bart Nessux]

    | > Here's the function... if the user wants to re-enter the
    | path name...
    | > I'm simply calling the function again... is this wrong???

    [... snip function ...]

    | Sorry... namespace pollution. Both the function
    | and a var within it were named "path_name"... I'm
    | an idiot... I need more coffee.

    Yes. That was the most immediate problem. But the other
    one is (only slightly) more subtle: you're going round
    again by having the function call itself. Now, while this
    will in fact work (it's called recursion, in case you've
    not come across the concept) it's not the best way to do
    this. All you need is a loop of this sort:

    <code>

    while 1:
    chosen_path = raw_input ("What is the path?")
    is_this_correct = \
    raw_input ("You chose: %s. Is this correct?" % chosen_path)

    if is_this_correct == 'Y':
    break
    elif is_this_correct == 'X':
    sys.exit ()
    elif is_this_correct == 'N':
    continue
    else:
    print "I'm sorry; I don't understand"

    </code>

    Obviously, there are all sorts of variations on
    this theme, but this will normally be a more
    natural fit for this kind of operation.

    TJG


    ________________________________________________________________________
    This e-mail has been scanned for all viruses by Star Internet. The
    service is powered by MessageLabs. For more information on a proactive
    anti-virus service working around the clock, around the globe, visit:
    http://www.star.net.uk
    ________________________________________________________________________
     
    Tim Golden, Jul 29, 2004
    #1
    1. Advertising

  2. Tim Golden

    Bart Nessux Guest

    Tim Golden wrote:
    > [Bart Nessux]
    >
    > | > Here's the function... if the user wants to re-enter the
    > | path name...
    > | > I'm simply calling the function again... is this wrong???
    >
    > [... snip function ...]
    >
    > | Sorry... namespace pollution. Both the function
    > | and a var within it were named "path_name"... I'm
    > | an idiot... I need more coffee.
    >
    > Yes. That was the most immediate problem. But the other
    > one is (only slightly) more subtle: you're going round
    > again by having the function call itself. Now, while this
    > will in fact work (it's called recursion, in case you've
    > not come across the concept) it's not the best way to do
    > this. All you need is a loop of this sort:
    >
    > <code>
    >
    > while 1:
    > chosen_path = raw_input ("What is the path?")
    > is_this_correct = \
    > raw_input ("You chose: %s. Is this correct?" % chosen_path)
    >
    > if is_this_correct == 'Y':
    > break
    > elif is_this_correct == 'X':
    > sys.exit ()
    > elif is_this_correct == 'N':
    > continue
    > else:
    > print "I'm sorry; I don't understand"
    >
    > </code>
    >
    > Obviously, there are all sorts of variations on
    > this theme, but this will normally be a more
    > natural fit for this kind of operation.
    >
    > TJG


    I understand recursion to be a loop or a loop to
    be recursion... however you prefer to look at it.
    Whether it's a function calling itself until the
    user gets the input right or a while statement w/i
    a function waiting for correct input... IMO, it's
    the same thing. With that said, there may be
    performance issues that I'm unaware of that make
    your approach better or worse than mine...
    outside that, I think either approach is worthwhile.
     
    Bart Nessux, Jul 29, 2004
    #2
    1. Advertising

  3. Tim Golden

    Bart Nessux Guest

    Tim Golden wrote:
    > [Bart Nessux]
    >
    > | > Here's the function... if the user wants to re-enter the
    > | path name...
    > | > I'm simply calling the function again... is this wrong???
    >
    > [... snip function ...]
    >
    > | Sorry... namespace pollution. Both the function
    > | and a var within it were named "path_name"... I'm
    > | an idiot... I need more coffee.
    >
    > Yes. That was the most immediate problem. But the other
    > one is (only slightly) more subtle: you're going round
    > again by having the function call itself. Now, while this
    > will in fact work (it's called recursion, in case you've
    > not come across the concept) it's not the best way to do
    > this. All you need is a loop of this sort:
    >
    > <code>
    >
    > while 1:
    > chosen_path = raw_input ("What is the path?")
    > is_this_correct = \
    > raw_input ("You chose: %s. Is this correct?" % chosen_path)
    >
    > if is_this_correct == 'Y':
    > break
    > elif is_this_correct == 'X':
    > sys.exit ()
    > elif is_this_correct == 'N':
    > continue
    > else:
    > print "I'm sorry; I don't understand"
    >
    > </code>
    >
    > Obviously, there are all sorts of variations on
    > this theme, but this will normally be a more
    > natural fit for this kind of operation.
    >
    > TJG


    I understand recursion to be a loop or a loop to
    be recursion... however you prefer to look at it.
    Whether it's a function calling itself until the
    user gets the input right or a while statement w/i
    a function waiting for correct input... IMO, it's
    the same thing. With that said, there may be
    performance issues that I'm unaware of that make
    your approach better or worse than mine...
    outside that, I think either approach is worthwhile.
     
    Bart Nessux, Jul 29, 2004
    #3
  4. On Thu, 29 Jul 2004, Bart Nessux wrote:

    > I understand recursion to be a loop or a loop to
    > be recursion... however you prefer to look at it.
    > Whether it's a function calling itself until the
    > user gets the input right or a while statement w/i
    > a function waiting for correct input... IMO, it's
    > the same thing. With that said, there may be
    > performance issues that I'm unaware of that make
    > your approach better or worse than mine...
    > outside that, I think either approach is worthwhile.


    The 'performance issue' at stake is that the stack is being slowly but
    surely eaten up using the recusive call... it's possible for a user to
    crash your program by repeatedly providing incorrect input.

    This programming style is enabled, however, by tail recursion elimination,
    as seen in Scheme, where such recursion would be the natural way to write
    your code. Not so in Python though -- a while loop is the one true way to
    go (as recently prounounced by Guido ;)).
     
    Christopher T King, Jul 29, 2004
    #4
  5. On 2004-07-29, Bart Nessux <> wrote:

    > I understand recursion to be a loop or a loop to
    > be recursion... however you prefer to look at it.


    A loop uses a finite amount of memory no matter how many times
    it loops. Recursion uses an unbounded amount of memory unless
    it's tail recursion and the compiler transforms it into a loop
    [the Python compiler does not].

    > Whether it's a function calling itself until the user gets the
    > input right or a while statement w/i a function waiting for
    > correct input... IMO, it's the same thing. With that said,
    > there may be performance issues that I'm unaware of that make
    > your approach better or worse than mine... outside that, I
    > think either approach is worthwhile.


    Just make sure you place bounds on the depth of the recurstion
    so you don't run out of stack space.

    --
    Grant Edwards grante Yow! Vote for ME
    at -- I'm well-tapered,
    visi.com half-cocked, ill-conceived
    and TAX-DEFERRED!
     
    Grant Edwards, Jul 29, 2004
    #5
  6. Tim Golden

    Peter Hansen Guest

    Bart Nessux wrote:

    > I understand recursion to be a loop or a loop to be recursion... however
    > you prefer to look at it.


    Absolutely not. Recursion is more like a spiral, rapidly closing
    in on itself until you're trapped in the middle, or maybe a
    swirling whirlpool that will sink your program over time...

    Just because you can use recursion to implement something that
    appears to loop doesn't mean it's a good idea. Much better
    to get out of that frame of mind... Recursion does _not_ get
    you back to where you were, as a real loop would.

    The key is to understand that each time you call a function,
    more data is put on the "stack", which has a finite size.
    Basically the context of the calling function is preserved
    when you call a subroutine, including all the local variables,
    plus the "return address" so the interpreter knows where to
    go back to.

    Whether you do it through recursion or some other means,
    if you get too deeply nested you will crash, and even if you
    don't you still have the overhead of "unwinding" all those
    stack frames when you finally return. It may look like
    it falls off the end of the function, but in fact it is
    actually returning to the previous stack frame, in the place
    just after where the function call was, then it returns from
    there to the previous stack frame, then returns to the previous
    one, each time popping a frame off the stack, all the way up
    to the top of the stack.

    While it might be okay for a trivial script that is just asking
    for user input, it is terribly bad style and you would do well
    to learn to do it differently.

    All IMHO, and theoretical discussions of tail recursion
    notwithstanding.

    -Peter
     
    Peter Hansen, Jul 29, 2004
    #6
  7. Tim Golden

    Bart Nessux Guest

    Peter Hansen wrote:
    > Bart Nessux wrote:
    >
    >> I understand recursion to be a loop or a loop to be recursion...
    >> however you prefer to look at it.

    >
    >
    > Absolutely not. Recursion is more like a spiral, rapidly closing
    > in on itself until you're trapped in the middle, or maybe a
    > swirling whirlpool that will sink your program over time...
    >
    > Just because you can use recursion to implement something that
    > appears to loop doesn't mean it's a good idea. Much better
    > to get out of that frame of mind... Recursion does _not_ get
    > you back to where you were, as a real loop would.
    >
    > The key is to understand that each time you call a function,
    > more data is put on the "stack", which has a finite size.
    > Basically the context of the calling function is preserved
    > when you call a subroutine, including all the local variables,
    > plus the "return address" so the interpreter knows where to
    > go back to.
    >
    > Whether you do it through recursion or some other means,
    > if you get too deeply nested you will crash, and even if you
    > don't you still have the overhead of "unwinding" all those
    > stack frames when you finally return. It may look like
    > it falls off the end of the function, but in fact it is
    > actually returning to the previous stack frame, in the place
    > just after where the function call was, then it returns from
    > there to the previous stack frame, then returns to the previous
    > one, each time popping a frame off the stack, all the way up
    > to the top of the stack.
    >
    > While it might be okay for a trivial script that is just asking
    > for user input, it is terribly bad style and you would do well
    > to learn to do it differently.
    >
    > All IMHO, and theoretical discussions of tail recursion
    > notwithstanding.
    >
    > -Peter


    Thanks to all for detailing how loops and
    recursion differ. I'm going with Tim's loop
    suggestion now that I realize why I shouldn't use
    recursion for this type of thing.
     
    Bart Nessux, Jul 29, 2004
    #7
  8. On Thu, 29 Jul 2004 13:17:34 -0400, Bart Nessux <> wrote:

    >Peter Hansen wrote:
    >> Bart Nessux wrote:

    [...]
    >>
    >> While it might be okay for a trivial script that is just asking
    >> for user input, it is terribly bad style and you would do well
    >> to learn to do it differently.
    >>
    >> All IMHO, and theoretical discussions of tail recursion
    >> notwithstanding.
    >>
    >> -Peter

    >
    >Thanks to all for detailing how loops and
    >recursion differ. I'm going with Tim's loop
    >suggestion now that I realize why I shouldn't use
    >recursion for this type of thing.


    OTOH, the default recursion depth limit is 1000, so you could
    have gotten 1000 tries before bumping into that.

    But there was still an error in your function besides the name collision
    that made the recursive call try to call the returned string of raw_input.

    The recursive call did not provide for returning a successful result, the
    way an immediate successful return did. I.e., the recursive call line
    should have been
    return path_name()
    not just
    path_name()

    BTW, some languages (e.g. scheme) mandate proper tail recursion, so it
    can be fine to implement looping via recursion, as Peter is alluding to
    (I think ;-) while providing advice for python style which I agree with.

    Regards,
    Bengt Richter
     
    Bengt Richter, Jul 29, 2004
    #8
  9. Tim Golden

    Peter Hansen Guest

    Bengt Richter wrote:

    > BTW, some languages (e.g. scheme) mandate proper tail recursion, so it
    > can be fine to implement looping via recursion, as Peter is alluding to
    > (I think ;-) while providing advice for python style which I agree with.


    Never having used tail-recursive languages, I won't pretend to
    be any kind of expert on proper style there...

    I'm curious though. Is it considered perfectly acceptable style
    to implement a "pure loop" in the form of recursion in a tail-
    recursive language, or is that feature really intended just to
    allow truly recursive algorithms to be implemented without
    fear of stack overflow or performance problems?

    The acceptance test would probably be: if a mature programmer
    in the language in question encountered a loop-done-as-recursion
    in code from, say, a junior programmer, would she refactor it to
    use a more conventional control structure (e.g. while, or for)
    or would she not give it a second thought?

    -Peter
     
    Peter Hansen, Jul 29, 2004
    #9
  10. Tim Golden

    Donn Cave Guest

    In article <>,
    Peter Hansen <> wrote:

    > Never having used tail-recursive languages, I won't pretend to
    > be any kind of expert on proper style there...
    >
    > I'm curious though. Is it considered perfectly acceptable style
    > to implement a "pure loop" in the form of recursion in a tail-
    > recursive language, or is that feature really intended just to
    > allow truly recursive algorithms to be implemented without
    > fear of stack overflow or performance problems?
    >
    > The acceptance test would probably be: if a mature programmer
    > in the language in question encountered a loop-done-as-recursion
    > in code from, say, a junior programmer, would she refactor it to
    > use a more conventional control structure (e.g. while, or for)
    > or would she not give it a second thought?


    Depends of course on the language, but there sure exist
    languages where "while" and "for" don't even exist (and
    hence are not conventional control structures.) Haskell
    is the one I know.

    That isn't an accident, they aren't omitted just because
    no one had time to implement them. Loops are an "imperative"
    construct that doesn't make sense in a pure functional
    language like Haskell. So I suppose that even where there's
    more support for imperative constructs, as I think there is
    in Scheme for example, a mature programmer of a Functional
    Programming persuasion might well on the contrary recode
    a loop to a recursive algorithm.

    Donn Cave,
     
    Donn Cave, Jul 29, 2004
    #10
  11. On Thu, 29 Jul 2004, Peter Hansen wrote:

    > I'm curious though. Is it considered perfectly acceptable style
    > to implement a "pure loop" in the form of recursion in a tail-
    > recursive language, or is that feature really intended just to
    > allow truly recursive algorithms to be implemented without
    > fear of stack overflow or performance problems?


    In Scheme, it's not only perfectly acceptable, it's the standard way to do
    things.

    > The acceptance test would probably be: if a mature programmer
    > in the language in question encountered a loop-done-as-recursion
    > in code from, say, a junior programmer, would she refactor it to
    > use a more conventional control structure (e.g. while, or for)
    > or would she not give it a second thought?


    Not being a mature Scheme programmer, I can't say for sure, but my gut
    feeling is that the exact opposite would happen; i.e. if the mature
    programmer found a loop utilizing do (Scheme's generalized looping
    construct), she would likely rewrite it using either recursion, or one of
    for-each or map. (I would provide an example, but my Scheme is wayyy to
    rusty for that ;).)
     
    Christopher T King, Jul 29, 2004
    #11
  12. Tim Golden

    Mel Wilson Guest

    In article <>,
    Donn Cave <> wrote:
    >In article <>,
    > Peter Hansen <> wrote:
    >> The acceptance test would probably be: if a mature programmer
    >> in the language in question encountered a loop-done-as-recursion
    >> in code from, say, a junior programmer, would she refactor it to
    >> use a more conventional control structure (e.g. while, or for)
    >> or would she not give it a second thought?

    >
    >Depends of course on the language, but there sure exist
    >languages where "while" and "for" don't even exist (and
    >hence are not conventional control structures.) Haskell
    >is the one I know.


    Ditto the conditional and macro expansion pseudo-ops in
    many Macro-Assemblers. Multics alm supported assembly-time
    loops with the `dup` pseudo-op, but with most assemblers
    I've seen, if you want repeated actions at assembly time,
    recursive macros are what you use.

    These ideas show up in the darndest places.

    Regards. Mel.
     
    Mel Wilson, Jul 29, 2004
    #12
  13. Tim Golden

    Remi Turk Guest

    On Thu, Jul 29, 2004 at 01:31:19PM -0700, Donn Cave wrote:
    > Depends of course on the language, but there sure exist
    > languages where "while" and "for" don't even exist (and
    > hence are not conventional control structures.) Haskell
    > is the one I know.
    >
    > That isn't an accident, they aren't omitted just because
    > no one had time to implement them. Loops are an "imperative"
    > construct that doesn't make sense in a pure functional
    > language like Haskell. So I suppose that even where there's
    > more support for imperative constructs, as I think there is
    > in Scheme for example, a mature programmer of a Functional
    > Programming persuasion might well on the contrary recode
    > a loop to a recursive algorithm.


    Except that as general recursion is in some aspects quite a bit
    like goto (power, readability etc), it is often preferred to
    refactor the recursion into it's own function: Higher-order
    functions like map, filter and reduce/fold. Which means that,
    in some ways, a language like Haskell _does_ have control
    structures (which are preferred over recursion),
    although those structures happen to also be functions.
    (I've (re)cursed (in) Prolog at college far too much,
    so I may be overreacting against explicit recursion <wink>

    Happy hacking,
    Remi

    --
    Nobody can be exactly like me. Even I have trouble doing it.
     
    Remi Turk, Jul 29, 2004
    #13
  14. In article <>, Peter Hansen wrote:

    > Never having used tail-recursive languages, I won't pretend to
    > be any kind of expert on proper style there...
    >
    > I'm curious though. Is it considered perfectly acceptable style
    > to implement a "pure loop" in the form of recursion in a tail-
    > recursive language,


    Yes. In Scheme, for example, there is some sort of looping
    construct, but it's considered a nasty, ugly wart on the
    language. In Scheme you're "supposed" to use tail recursion
    where you would use a "for" loop in Python.

    > The acceptance test would probably be: if a mature programmer
    > in the language in question encountered a
    > loop-done-as-recursion in code from, say, a junior programmer,
    > would she refactor it to use a more conventional control
    > structure (e.g. while, or for) or would she not give it a
    > second thought?


    The latter. In fact, if a mature programmer found a looping
    construct, he would be likely to refactor it into
    tail-recursion.

    --
    Grant Edwards grante Yow! I will establish
    at the first SHOPPING MALL in
    visi.com NUTLEY, New Jersey...
     
    Grant Edwards, Jul 30, 2004
    #14
  15. Tim Golden

    Terry Reedy Guest

    "Bart Nessux" <> wrote in message
    news:...
    > I understand recursion to be a loop or a loop to
    > be recursion... however you prefer to look at it.


    If you qualify the recursion as simple (non-branching), then I agree. They
    are two different syntaxes for expressing simple induction (repetition with
    variation). Looping can be thought of as anonymous within-frame recursion.
    And some languages implement tail recursion this way. But Python does not,
    and I believe a majority of Pythoneers prefer the loop version. For enough
    repetitions, it is mandatory. And for general sequence processing, for
    loops are most excellent.

    Branching recursion is more complicated. In general, three loops are
    required to replace one (branching) recursion, but that's another story...

    Terry J. Reedy
     
    Terry Reedy, Jul 30, 2004
    #15
  16. Tim Golden

    Terry Reedy Guest

    "Christopher T King" <> wrote in message
    news:p...
    > your code. Not so in Python though -- a while loop is the one true way

    to
    > go (as recently prounounced by Guido ;)).


    Actually, Python's for loops are usually the way to go ;-)
    (tho not in the OP's case as presented)

    Terry J. Reedy
     
    Terry Reedy, Jul 30, 2004
    #16
  17. Bart Nessux <> writes:

    > I understand recursion to be a loop or a loop to be recursion...


    No, loop is _iteration_.
     
    Tor Iver Wilhelmsen, Jul 30, 2004
    #17
    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. Bart Nessux

    A goto-like usage of a function

    Bart Nessux, Jul 29, 2004, in forum: Python
    Replies:
    2
    Views:
    289
    Scott David Daniels
    Jul 30, 2004
  2. Patrick Kowalzick
    Replies:
    5
    Views:
    500
    Patrick Kowalzick
    Mar 14, 2006
  3. higer
    Replies:
    8
    Views:
    341
  4. fabsy

    goto function?

    fabsy, Aug 15, 2006, in forum: Ruby
    Replies:
    21
    Views:
    289
    N Okia
    Aug 24, 2006
  5. Helgitomas Gislason

    "Goto line" function?

    Helgitomas Gislason, Mar 9, 2007, in forum: Ruby
    Replies:
    3
    Views:
    138
    Brian Candler
    Mar 10, 2007
Loading...

Share This Page