Walter Bright wrote:
Don wrote:
The math functions need to work for any rounding mode, not just the
default mode. They also set the status flags correctly. In fact, they
are almost the only functions where this matters!
Ok, then std.math functions cannot be pure in either your or my
proposal, so I'm not seeing the advantage of yours.
They _can_ be pure in my proposal.
Take real y = exp(real x) as an example.
Actually what happens is:
y = exp(real x, threadlocal int controlflags);
threadlocal int statusflags |= exp_effect_statusflags(real x,
threadlocal int controlflags);
To make exp() pure, we need to get rid of those two thread local variables.
Take the basic version of my proposal: 'pure' functions in floatingpoint
modules cannot be cached at all.
Nonetheless, they can be called by pure functions in normal functions,
and those functions _can_ be cached.
This works because in a normal function, the control flags are defined
to be in the default state. The 'caching only possible when called from
a normal module' thus means that caching only happens when the control
flags are in the default state'. The global variable has been turned
into a compile-time constant.
The status flags are stated to be an undefined state inside non-floating
point modules, so the fact that they keep changing is irrelevant. The
caching system can therefore ignore the fact that the status and control
registers exist.
It's only when a function in a floatingpoint module calls a pure
function which is also in a floatingpoint module, that we have a
guarantee that the caching system will not interfere. This very simple
rule is all we need.