renaming 'references' to functions can give recursive problems

Discussion in 'Python' started by peter, Feb 16, 2005.

  1. peter

    peter Guest

    Hello all,

    Recently I've started to refactor my code ...(I'm using python 2.3.4)
    I tried to add extra functionality to old functions non-intrusively.
    When I used a construct, which involves renaming functions etc... I
    came across some recursive problems. (a basic construct can be found
    under the section BASIC CODE)

    These problems do not occur when renaming objects. (see section EXTRA
    CODE)
    My question now is:
    I do not know the underlying idea of functions. Is this the way they
    should behave? Or should they work the same way as objects do?
    (My preferences goes to this last option)

    BASIC CODE:
    ---------------------------------------------------------------------------
    def fA(input): # starting point: function named fA
    return input

    def newFA(input): # new function with added functionality
    #does something extra with a!
    return fA(input)
    fA = newFA
    # this should allow to add functionality without
    # breaking older code which uses the name fA!
    fA() # execute fA()
    ----------------------------------------------------------------------------
    problem: you get...
    File "recursivemethods.py", line 7, in newFA
    return fA(input)
    RuntimeError: maximum recursion depth exceeded

    when using objects this problems does not occur...
    EXTRA CODE:
    ----------------------------------------------------------------------------
    PYTHON-CODE # REMARKS
    referenceA = SomeObject() # referenceA -> SomeObject()
    # references to the memory space of
    # some object
    referenceB = referenceA # referenceB -> SomeObject()
    # is also a reference to ...
    referenceA = referenceB # referenceA references to SomeObject()

    # now for functions!
    fA = function # fA references to memory space
    # of a function

    def newFA(input): # newFA references to a function
    return fA(input) # which holds a reference to fA.
    # Notice the important difference with objects!
    # newFA holds a reference to the reference fA
    # When using object you reference to
    # the memory space of fA!!!
    fA = newFA
    fA() # recursive problems!!!
    --------------------------------------------------------------------------
     
    peter, Feb 16, 2005
    #1
    1. Advertising

  2. peter

    peter Guest

    see the topic:
    adding new functionality to a function non-intrusively! and decorators
    if you want to add functionality to a function!
     
    peter, Feb 16, 2005
    #2
    1. Advertising

  3. Op 2005-02-16, peter schreef <>:
    > Hello all,
    >
    > Recently I've started to refactor my code ...(I'm using python 2.3.4)
    > I tried to add extra functionality to old functions non-intrusively.
    > When I used a construct, which involves renaming functions etc... I
    > came across some recursive problems. (a basic construct can be found
    > under the section BASIC CODE)
    >
    > These problems do not occur when renaming objects. (see section EXTRA
    > CODE)
    > My question now is:
    > I do not know the underlying idea of functions. Is this the way they
    > should behave? Or should they work the same way as objects do?
    > (My preferences goes to this last option)
    >
    > BASIC CODE:
    > ---------------------------------------------------------------------------
    > def fA(input): # starting point: function named fA
    > return input
    >
    > def newFA(input): # new function with added functionality
    > #does something extra with a!
    > return fA(input)
    > fA = newFA
    > # this should allow to add functionality without
    > # breaking older code which uses the name fA!
    > fA() # execute fA()


    Try this:

    def fA(input):
    return input


    def newFA(input, f= fA):
    return f(input)

    fA = newFA

    --
    Antoon Pardon
     
    Antoon Pardon, Feb 16, 2005
    #3
  4. peter

    peter Guest

    Hello, nice solution:
    but it puzzles me :)

    can anyone tell me why
    -----------correct solution----------------
    def fA(input):
    return input

    def newFA(input, f= fA):
    return f(input)

    fA = newFA

    is correct and:
    -------------infinite loop-----------------

    def fA(input):
    return input

    def newFA(input):
    return fA(input)

    fA = newFA

    gives an infinite recursive loop?

    kind regards

    Peter

    Antoon Pardon wrote:
    > Op 2005-02-16, peter schreef <>:
    > > Hello all,
    > >
    > > Recently I've started to refactor my code ...(I'm using python

    2.3.4)
    > > I tried to add extra functionality to old functions

    non-intrusively.
    > > When I used a construct, which involves renaming functions etc... I
    > > came across some recursive problems. (a basic construct can be

    found
    > > under the section BASIC CODE)
    > >
    > > These problems do not occur when renaming objects. (see section

    EXTRA
    > > CODE)
    > > My question now is:
    > > I do not know the underlying idea of functions. Is this the way

    they
    > > should behave? Or should they work the same way as objects do?
    > > (My preferences goes to this last option)
    > >
    > > BASIC CODE:
    > >

    ---------------------------------------------------------------------------
    > > def fA(input): # starting point: function named fA
    > > return input
    > >
    > > def newFA(input): # new function with added functionality
    > > #does something extra with a!
    > > return fA(input)
    > > fA = newFA
    > > # this should allow to add functionality without
    > > # breaking older code which uses the name fA!
    > > fA() # execute fA()

    >
    > Try this:
    >
    > def fA(input):
    > return input
    >
    >
    > def newFA(input, f= fA):
    > return f(input)
    >
    > fA = newFA
    >
    > --
    > Antoon Pardon
     
    peter, Feb 16, 2005
    #4
  5. peter wrote:

    >Hello, nice solution:
    >but it puzzles me :)
    >
    >can anyone tell me why
    >-----------correct solution----------------
    >def fA(input):
    > return input
    >
    >def newFA(input, f= fA):
    > return f(input)
    >
    >fA = newFA
    >
    >is correct and:
    >
    >
    >>> def fA(input):

    .... print "inside fA"
    .... return input
    ....
    >>> def newFA(input,f=fA):

    .... print "inside newFA"
    .... return f(input)
    ....
    >>> fA = newFA
    >>> fA(2)

    inside newFA
    inside fA
    2

    while:

    >-------------infinite loop-----------------
    >
    >def fA(input):
    > return input
    >
    >def newFA(input):
    > return fA(input)
    >
    >fA = newFA
    >
    >gives an infinite recursive loop?
    >
    >
    >


    >>> def fA(input):

    .... print "inside fA"
    .... return input
    ....
    >>> def newFA(input):

    .... print "inside newFA"
    .... return fA(input)
    ....
    >>> fA = newFA
    >>> fA(2)

    inside newFA
    inside newFA
    inside newFA
    inside newFA


    What is happening is that when you call fA (inside newFA) in the second
    case, you are calling newFA because fA is pointing to newFA (hope that
    made sense ;-)). So it was recursive. While in the former case you
    called f, which pointed to fA, but not to newFA. Probably the following
    will make it clearer:


    >>> def fA(input):

    .... print "inside fA"
    .... return input
    ....
    >>> def newFA(input,f=fA):

    .... print "inside newFA"
    .... print "f is pointing to: ",f
    .... return f(input)
    ....
    >>> fA = newFA
    >>> fA(2)

    inside newFA
    f is pointing to: <function fA at 0x43123374>
    inside fA
    2
    >>> fA

    <function newFA at 0x43194064>
    >>> newFA

    <function newFA at 0x43194064>

    Thus f and fA do not point to the same function object when you execute
    the statement fa(2). This f is called once and terminates.


    thanks,
    Satchit
     
    Satchidanand Haridas, Feb 16, 2005
    #5
  6. peter wrote:
    > Hello, nice solution:
    > but it puzzles me :)
    >
    > can anyone tell me why
    > -----------correct solution----------------
    > def fA(input):
    > return input
    >
    > def newFA(input, f= fA):
    > return f(input)
    >
    > fA = newFA
    >
    > is correct and:
    > -------------infinite loop-----------------
    >
    > def fA(input):
    > return input
    >
    > def newFA(input):
    > return fA(input)


    In newFA, fA is not bound until you call newFA. By which time you've re-bound
    fA to newFA, causing the recursion. In the 'correct' solution above, f is bound
    to the original fA function at the time the def fA statement is executed, which
    is what you want.

    >
    > fA = newFA
    >
    > gives an infinite recursive loop?
    >
    > kind regards
    >
    > Peter


    Regards
    Michael
     
    Michael Spencer, Feb 16, 2005
    #6
  7. "peter" <> wrote
    > ----------------------------------------------------------------------------
    > PYTHON-CODE # REMARKS
    > referenceA = SomeObject() # referenceA -> SomeObject()
    > # references to the memory space of
    > # some object
    > referenceB = referenceA # referenceB -> SomeObject()
    > # is also a reference to ...
    > referenceA = referenceB # referenceA references to SomeObject()
    >
    > # now for functions!
    > fA = function # fA references to memory space
    > # of a function


    nope. it refers to a function object. function objects are no different
    from ordinary objects.

    > def newFA(input): # newFA references to a function


    not yet.

    > return fA(input) # which holds a reference to fA.


    nope. the function does not hold a reference to fA. fA is a global,
    and will be resolved at runtime.

    > # Notice the important difference with objects!
    > # newFA holds a reference to the reference fA


    no, it doesn't hold a reference to the reference. it contains the name
    "fA", and will look for that when you call it.

    > # When using object you reference to
    > # the memory space of fA!!!


    you're confused. resetting your brain and reading the documentation
    again might help:

    http://docs.python.org/ref/objects.html
    http://docs.python.org/ref/naming.html

    </F>
     
    Fredrik Lundh, Feb 16, 2005
    #7
  8. peter

    peter Guest

    brain reset and understood

    thx a lot for all your answers

    Peter
     
    peter, Feb 16, 2005
    #8
  9. peter

    Jeff Shannon Guest

    peter wrote:

    > Hello, nice solution:
    > but it puzzles me :)
    >
    > can anyone tell me why
    > -----------correct solution----------------
    > def fA(input):
    > return input
    >
    > def newFA(input, f= fA):
    > return f(input)


    This saves a reference to the original function in the new function's
    default argument.

    > -------------infinite loop-----------------
    >
    > def fA(input):
    > return input
    >
    > def newFA(input):
    > return fA(input)


    This does not save any reference to the original function; it simply
    does a run-time lookup of the name, and uses whatever object is
    currently bound to that name. Since you later rebind the name to this
    new function, it's simply calling itself.

    Jeff Shannon
    Technician/Programmer
    Credit International
     
    Jeff Shannon, Feb 16, 2005
    #9
  10. peter wrote:
    > brain reset and understood
    >
    > thx a lot for all your answers
    >
    > Peter
    >

    Now that you've got reset, you might want to consider an alternative solution:

    def fA(input):
    return input

    oldfA = fA # Hold a reference to the the old function

    def newFA(input):
    "Do something new"
    return oldfA(input)

    fA = newFA


    The advantage of this is that you don't need to change the function newfA at all
    when you're ready to rename it.

    Michael
     
    Michael Spencer, Feb 17, 2005
    #10
    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. hokiegal99
    Replies:
    5
    Views:
    332
    Peter Hansen
    Jul 19, 2003
  2. grocery_stocker
    Replies:
    10
    Views:
    633
    Keith Thompson
    May 25, 2005
  3. Lars Willich
    Replies:
    13
    Views:
    843
    Ian Shef
    Oct 23, 2007
  4. Fabian von Romberg

    Renaming references when compiling

    Fabian von Romberg, Oct 28, 2007, in forum: ASP .Net
    Replies:
    0
    Views:
    294
    Fabian von Romberg
    Oct 28, 2007
  5. vamsi
    Replies:
    21
    Views:
    2,085
    Keith Thompson
    Mar 9, 2009
Loading...

Share This Page