1
$\begingroup$

I've noticed a pattern in trying to make functional programming effective - there is still some kind of impure, effectful operation going on, but it gets holed up in a single, manageable imperative operation. For example, in Redux - the whole Redux store is a giant, mutable, singleton global variable. Normally we should be terrified to use such a monstrosity, but due to the way its framework has it neatly packed away in a safe, managed space, we can use it safely and have access to all its global, mutable, singleton benefits. Similarly Haskell - you return basically a data value (mind you a very complex data value) representing your program, to what is ultimately a mutable, global, single runtime that interprets and executes it. You still need the effect at some level, or it won't be useful.

So the idle musing is this - is there some sense, anywhere in the literature, where it is valid to look at even calling a function as being an effect of its own? And let's assume this is an otherwise pure function calling a pure function - is this just a part of the execution model we assume as pure enough to not count?

$\endgroup$
1
  • $\begingroup$ Spending time and electricity and turning energy into heat can be thought of as a side effect, and it can be reasoned with by complexity analysis. $\endgroup$
    – Trebor
    Commented Jun 24 at 13:24

1 Answer 1

1
$\begingroup$

No, normally calling a function is not considered a side effect.... but if that function has side effects, then calling it does cause side effects.

You might be looking for the notion of observational purity. If you have an implementation of an API that, for all callers of the API, is indistinguishable from pure (behaves identically to a pure implementation, has no observable side effects), then we call it observationally pure. In most contexts, this is good enough to achieve all of the benefits of a pure function, so you can consider it pure if you like. For instance, the function implementation might temporarily mutate internal variables as part of the computation, but still the result is a deterministic function of its inputs and the computation has no externally visible side effects -- if so, we're justified to call it observationally pure.

Your example of Redux is not observationally pure. It contains mutable shared state that is externally visible. You are absolutely not justified to consider read/write operations on Redux pure.

It's certainly valid to call such functions. There is still benefit to structuring your code in this way. But such functions are not pure. This is not a black-and-white situation where either your entire program is pure and life is golden or your entire program is not pure and life is awful. There can be benefits to making part of the code functional and walling away the imperative parts or the mutable shared state to a well-contained component with a well-specified interface.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.