Search code examples
functional-programmingpurely-functional

Can functions with non-pure arguments of type functions be pure?


Can functions that take non-pure functions as arguments be considered pure if they do not change/store state directly, don't reference global variables etc? Where and how do we draw the line on what is pure and what is not, is it solely on the function's in question code or do we take into account the effects of invoking the arguments?

E.g. imagine this scenario, where the pure function represents a stateless workflow and takes as arguments a few actions to be executed during this workflow. One of these actions changes some state somewhere. So if I'm looking strictly at the implementation of my workflow, it seems pure, but eventually it does modify state by invoking this parameter function that modifies state. I'm tempted to speculate the workflow is also non-pure, but passing in a different argument that does not change state will make it pure, so I'm confused.

Any help will be much appreciated. Thank you.


Solution

  • (define (its-not-me launch-rockets)
       (lambda () 
          (launch-rockets)))
    

    is indeed pure. It doesn't launch rockets, it just constructs a computation that will, if called. But no side effects are caused by merely constructing such computation.

    (define (it-is-me launch-rockets)
       (launch-rockets)
       ((its-not-me launch-rockets)))
    

    does indeed launches the rockets, twice. Whether directly or indirectly, doesn't matter. If it causes side effects during its execution, it causes side effects during its execution.

    And if we have

    (define (launch-rockets)
       (if (prime? (random-integer))
          (do-actually-launch-rockets)
          (list 'do-nothing)))
    

    nothing changes. The first is still pure, constructing a computation which is potentially causing side-effects, is impure.

    Even

    (define (launch-rockets)
       (if (prime? (random-integer))
         (list 'i-am-only)
         (list 'kidding)))
    

    isn't a pure function, as it uses a non-pure effect, the randomness. Pure functions always return same result for the same arguments.