PureIt is nice if your function is weakly pure (doesn't read or write to global mutable state) or strongly pure (as weakly pure, and additionally doesn't dereference any of its argument pointers to mutable state) because the same inputs will then always yield the same outputs. The compiler can assume things about your function, replace function calls with cached results, or constant-fold everything.
It is nice if your function doesn't allocate memory, guaranteed. That's faster, that's compatible with more algorithms (leaves your callers in control about how to allocate), and makes your function simpler.
It is nice if your function cannot throw exceptions. Need fewer things in the mind before the code is complete and handles all conditions. Thus, it's simpler.
It is nice if your method promises to not modify the object. Your readers can reason about the system's state more easily, and focus on the real problems.
It is nice if your function, if it promises to return a class object by reference, guarantees that the reference is not null (we had this rant).
It is nice if ...
It is terrible if everything in your code is annotated with
@property @safe const pure nothrow @nogc:
It looks ugly and complex.
It's brittle because simple changes produce nasty, cascading errors.
It's unworkable if only 98 % of your language's standard library follows the principle, you call into the standard library everywhere, and even if you file bugs or send patches to the library, it will take months before the changes have propagated to your self-building users.
It tempts to cheat the system. Surely, to
round() a floating-point number
should be pure? What if, in general, yes, it is pure, but only on one particular architecture, the library writes custom float-handling flags to the CPU, then rounds, then restores the old flags? Such assembler calls are the most impure building blocks of any function. Let us consider this hack to cast between pure and impure... Oh, some well-optimizing compiler doesn't like the hack 3 years down the road, and you get segfaults in unrelated-looking parts of the source.
It runs into rarely-used parts of your language. These parts tend to be particularly buggy and lack the necessary manpower. These parts are notoriously incompatible anytime you want to mix two features of the language.
Likely, at least one of these features was designed 15 years ago, and then software engineering theory has advanced, but the language is encrusted enough to stick with the old design.
Arg arg arg. This must be why people write their own toy languages all the time.
Crane: In your
purity proposal, can you allow pointer dereferences to immutable external memory? Can Pascal guarantee that some object will never mutate? Typically, immutability and purity go hand-in-hand to make strong purity more usable.
-- Simon