One pain point with pure functions is you can't insert debug logging statements. D has a special case for that - purity for a statement isn't checked if it is prefixed with the `debug` keyword:
pure int square(int x) {
debug printf("called square\n");
return x * x;
}
which is very, very handy.I.e. it's for conditionally inserting debugging code where you don't care about purity, you just want to find the bug.
https://d.godbolt.org/z/Rwu4Cq (remove "-d-debug" to see)
Allocators are often pure in D, they probably shouldn't be but that would mean allocating outside the function which would be ugly and probably buggy too
Forgive me I'm just a small brained firmware programmer.
That's not a very useful distinction, and usually one talks about "purity" at a conceptual level. The language provides a layer of abstraction in which things can be considered pure (or not), even if the underlying implementation e.g. makes optimizations that require mutation. The language is just a guarantee that you can ignore these aspects of its implementation.
A function that allocates memory isn't pure, except perhaps iff it frees that memory either itself or by compiler magic. Then perhaps it is.
You can even promise a func is pure without even implementing it in the same translation unit! That produces lots of improvement. See these two godbolt links:
Actually that's the main point, as if it's in the same TU, the compiler can probably figure out a function is pure.