All purity does is force you to change the type of a function that wants to log something, to reflect that it’s returning a value that, when evaluated at run-time, will have the side-effect of printing to the console. It’s still a pure function since it returns the same description given the same argument(s), the only difference is that when this description is evaluated by the run-time system, something will be printed to the console (in accordance with the description).
In other words, you’re not restricting the effects your program can have, only how you can choose to describe them (as first-class values whose evaluation has a side-effect that is not observable by your code).
It’s all explained perfectly in this talk: https://www.infoq.com/presentations/io-functional-side-effec...
You can't counter that with an example of a program that you can't write as a pure function.
The idea of pure functions is a false friend in CS because it tries to solve the problem of state by wrapping it up and wishing it away.
It's true that state causes a lot of problems, but so many useful systems rely on mutable state - at practical application levels - that it might be interesting to design robust systems that manage state, context, and relationship instead of trying to create contrived examples of state-free systems.
There seems to be a cognitive bias against this in CS. Most developers appear to love puzzle systems made of hard little components with solid edges, and thinking in terms of context and relationships seems to be disturbingly alien. So there aren't many programming paradigms that explicitly work with contextual inference instead of trying to rigidly delimit interfaces.
But there are real prizes to be won from associative context-smart computing, and IMO the domain is wide open for innovation - because it may be possible to give up the pursuit of complete safety and predictability (which doesn't exist anyway) in return for new kinds of powerful, productive, and smart features.
I don't understand why any of this means you can't have a compile as a pure function. A pure function can cope with things changing internally - it just creates new data structures to represent things that have changed in the old data structures and then passes the new data structures onto the next phase.
A pure function just means you can't do something like a package manager that needs to read files from disk or download things.
> but so many useful systems rely on mutable state
You don't have to argue this to me - I wrote the first half of my PhD on the importance of mutable state.
I'm just arguing against the nonsense that it is impossible to write a useful real-world application as a pure function.
I work in the VM research group at Oracle, and guess what? Our JIT compiler is basically a pure function. It takes in some bytecode and produces some machine code. It's structured a little differently in reality, but it is logically, and almost in practice, a pure function from one to the other.
I'm writing a presentation about this right now.
I also agree - context and state are important and useful, because many real-life problems or processes rely on such a model and thus translate naturally when state is a "first-class citizen."
Some programs are simply pure functions. If your program entry point accepts a string and returns a string, then you can write useful things, such as compilers, image processing, grep, etc, entirely as pure functions.