Search code examples
c++haskellfunctional-programmingimperative-programming

disadvantage of pure function in functional programming


A pure function in functional programming is the one which do not have side effects. One of the meanings of this is it can not change the values of input parameters. Can this be seen as disadvantage for the memory utilization?
e.g. Lets say I have a function which simply takes a list and add another element in it. In C++ it could be as simple as


void addElem(std::vector& vec, int a)
{
    vec.insert(a);
}

This function clearly doesn't use much memory than already taken by passed object.
But same in Haskell will come to something like this.

addElem :: [Int] -> Int -> [Int] 
addElem xs a = xs ++ [a]

Now in this computation as xs is not changing it's value. So am I correct in saying that at some time the function will be consuming the memory double size of xs, one for xs and other for the return value. Or somehow lazy invocation makes sure that actually xs is only getting returned by adding only one element at the end?
I know that Monad is the way to have something which can have side effect. But can Monad be used to simply modify the input and return it's value?
Also can changing xs ++ [a] to a:xs consumes less memory?


Solution

  • Purity implies that the function cannot make destructive updates, so if

    xs ++ [a]
    

    is fully evaluated, a copy of xs must be made. That can happen in constant space if xs is lazily generated and not referenced anywhere else, so that it can be garbage collected as it is created. Or it can need a copy besides xs - but purity allows the cells of both lists to point to the same data, so the data need not be copied, only the spine (amended by the final cons). But if a copy is made, the old value xs is still available.

    Also can changing xs ++ [a] to a:xs consumes less memory?

    Yes, that one can simple reuse xs, all that needs is to create a new list cell and let its tail pointer point to xs.

    From a comment:

    I don't want C++ function to be pure. I want it to change the state of input. And that is what I wanted to be the whole point of the question.

    In that case, you need an impure function/action. That is possible for some data structures to implement, but for lists, the cells have to be copied/constructed anew. But adding an element to a std::vector<T> may also need reallocation.