Walter Bright wrote:
Don wrote:
A has called a function in B. B is not a floatingpoint module, so b() can only be called when the mode is set back to the default. a() violates this contract, so a() is incorrect. There's nothing wrong with b() or c(). If a() wants to call b(), it needs to restore the mode first; or else change b() into another floatingpoint module.

Ok, this was the missing piece in my understanding of the proposal.

But this requires that std.math either be floatingpoint, or two versions of it must exist if you want to do change the rounding modes on it.

I'm proposing that std.math would be floatingpoint. The docs contain references to the sticky flags; I just went to a lot of trouble to make sure that exp() sets the sticky flags correctly.


Something interesting about my proposal is that although it is motivated by the purity problem, that's simply a rule for the compiler -- the rules for programmers do not involve purity at all.(See my other post). Do not call _any_ functions in non-floatingpoint modules (pure or not) without restoring the rounding modes back to the default.

They could be done in terms of pure - if you call any pure function, the modes must be set to the default.

(1) If it's totally forbidden to call a pure function with non-default rounding modes, you need a separate non-pure function for the non-default case. And unfortunately, it's viral -- you'd need non-default rounding mode functions for every function. Even though these functions are the same for pure and non-pure.

(2) You could do it as, 'pure' is cacheable only if the control mode is set to default, otherwise it's not allowed to be cached. That would require the complier to check the control mode all the time if it's implementing caching. And it has to check it on EVERY function, it can't rely on the signature. Something like:

pure int foo(int x)
{
   return (x*0.5 > 6.0)? 1 : 2;
}

depends on the rounding mode! Consider that this might be in a library -- I just don't think it's viable.

Additionally, in both cases, you either lose access to the sticky flags, or else have to deal with them explicitly.

(3) There is another option which would actually work. That is to introduce a secret threadlocal 'must_not_cache_pure_functions' bool variable.

At any point where the mode is about to change, must_not_cache_pure_functions must be set to true, and set to false when the mode is restored. Likewise, that variable should be set to true whenever you're beginning a scope where you care about the sticky flags.

_Every_ attempt to use the cached result of a pure function would have to check that bool before doing anything else.

Reply via email to