Proposal: fixing the 'pure' floating point problem.

Don nospam at nospam.com
Tue Mar 17 04:42:55 PDT 2009


Walter Bright wrote:
> Don wrote:
>> 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.
> 
> If std.math was floatingpoint, then its functions could not be pure.

It can certainly be floatingpoint. That's the whole point of the 
proposal! Fundamental to the proposal is to relax the definition of pure 
from, "the result depends only on the input parameters, and has no 
side-effects" to (in x86 terminology)
"the result depends only on the inputs _and on the floating-point 
control register_, and has no side-effects _other than on the 
floating-point status register_".

Because without this relaxed definition, either
(1) any function with any floating-point operation cannot be pure; or
(2) access to the control and status registers is forbidden (the Java 
solution).

With this changed definition of pure, pure is not the same as "trivially 
cacheable". I think this is the key point which you haven't understood.

Every function in std.math fulfills the relaxed requirement for purity, 
though they are not "trivially cacheable", and don't satisfy the rigid 
purity rule.

Relaxed purity isn't much use for the caching optimization (though it 
helps for the other benefits of 'pure'). So, I then introduce 
module(floatingpoint) as a trick to make almost all pure functions 
"trivially cacheable".

All pure functions are trivially cacheable, unless they are defined in a 
floatingpoint module, AND are called from another floatingpoint module.

That tiny relaxation of the purity rules is enough to allow things like 
interval arithmetic to be implemented. In every other circumstance, the 
rigid purity rule can be applied.

So we get three desired outcomes:
(1) floating point can be used in pure functions;
(2) we have access to the control and status registers;
   2a. (but only in very limited circumstances);
(3) pure functions can be trivially cached;
   3a. (except in very limited circumstances).



More information about the Digitalmars-d mailing list