Proposal: fixing the 'pure' floating point problem.

Don nospam at nospam.com
Mon Mar 16 05:27:28 PDT 2009


Michel Fortin wrote:
> On 2009-03-16 04:03:01 -0400, Don <nospam at nospam.com> said:
> 
>>> In Don's proposal, the following is legal:
>>>
>>> -------------------------
>>> module A(floatingpoint);
>>> pure void a()
>>> {
>>>      set mode;
>>>      b();
>>>      restore mode;
>>> }
>>> ------------------------
>>> module B(floatingpoint);
>>> pure void b()
>>> {
>>>      do stuff;
>>> }
>>> -------------------------
>>>
>>> because, from compiler's perspective, they're
>>>
>>> struct FpuState { mode; sticky; }
>>> pure FpuState a(FpuState s);
>>> pure FpuState b(FpuState s);
>>>
>>> and can be actually cached, if compiler so wishes.  IIUC, this is
>>> exactly the use case when you implement range arithmetics.
>>
>> Hooray! Someone's understood the proposal.
> 
> 
> Interestingly, it's almost the same thing as I proposed earlier in this 
> thread. In my proposal what you can declare floating-point-flag-neutral 
> are functions instead of modules, and you wouldn't need a statement to 
> set and restore the mode as it'd be done automatically when calling a 
> function declared for a given mode. Said mode could be explicit or 
> neutral, the latter meaning the function accepts any mode.
> 
> My thinking is that forcing flag changes on function boundaries should 
> make it easier for the compiler than set/restore statements, while 
> ensuring they're properly scoped.
> 
> Here's what it could look like:
> 
>     pure float a()  // floatmode(round_nearest)  is assumed when omitted
>     {
>         // compiler sets the float mode to round down according to b's 
> declaration.
>         b(); // now can call b with the right mode
>         // compiler restores float mode to round_nearest (this 
> function's mode)
>         // calls to b can be easily memoized since b always use the same 
> float mode
>     }
> 
>     pure float b() floatmode(round_down)
>     {
>         return c(1); // call c with the current settings (becuase c is 
> float-mode-neutral)
>         // calls to c can be memoized within the boundaries of b because 
> the round
>         // mode won't change inside b.
>     }
> 
>     pure float c(float) floatmode(neutral)
>     {
>         // do stuff in the caller's floating point mode
>     }
> 
> 
> And to set all functions in a module as being float-mode-neutral, do it 
> like like you'd do for extern(C), or pure:
> 
>     module std.math;
> 
>     floatmode(neutral):
> 
>     // write you functions here.

That requires a new keyord, four new calling conventions, a new name 
mangling scheme, compiler insertion of special code, nasty issues with 
function pointers, ...
for a feature that almost nobody will ever use. And it doesn't deal with 
   dynamic rounding mode. And it doesn't solve the problem of the sticky 
flags.

It's not the same as my proposal, at all.



More information about the Digitalmars-d mailing list