Search code examples
pythonrecursionsummutablemutation

Is changing a variable in a recursive call considered mutation


My goal is to sum a list without using mutation.

def noMutObj(lst,pointer=0, result=0):
    if pointer == len(lst): 
        return result
    newResult = result + lst[pointer]
    return noMutObj(lst, pointer+1, newResult) 

Would we consider pointer mutating as we take a step into the recursion, or does mutation apply only to a variable changing in a iterative loop?


Solution

  • You haven't mutated pointer: you've passed a different value into each call to noMutObj. Each stack frame has its own pointer, none of which are changed. Even then, you would be changing only your local copy.

    You would have mutation if you did something such as

    lst.append(newResult)
    return noMutObj(lst, pointer+1, newResult)
    

    Before the call. Instead, the proper way to send an altered list to the next call would be something such as

    return noMutObj(lst[:].append(newResult), pointer+1, newResult)
    

    ... which creates a new list, appends newResult and passes that temporary object to the next level.

    I know this is not at all what you intended your function to do; I'm merely illustrating the syntactic and semantic principles.

    UPDATE

    Ah ... now that we have a purpose ...

    Mutation:

    def noMutObj(lst):
        if len(lst) == 0: 
            return 0
        return lst.pop() + noMutObj(lst)
    

    No mutation:

    def noMutObj(lst):
        if len(lst) == 0: 
            return 0
        return lst[0] + noMutObj(lst[1:])