
I'd like to direct folks' attention to the IEEE-utils package on hackage
[1], which Matt Morrow started and I have made a few additions to. There are
bindings to set and check the rounding mode, as well as check and clear the
exception register. On top of that I've built a very experimental monadic
wrapper (so experimental that I just noticed a typo in the documentation).
The monad is essentially a newtype over IO, which enforces a single IEEE
state using an MVar propagated through the program as an implicit parameter
(as opposed to created with top-level unsafePerfomIO). Strictness could
probably be enforced in a more thoroughgoing fashion, but now is explicitly
introduced with "calculate" which is a lifted "evaluate."
The perturb function is pretty neat -- it uses polymorphism to prevent
memoization, such that the same pure calculation can be performed over
different rounding modes, to test for numeric stability. I couldn't think of
a sane way to deal with fancier traps to the IEEE registers, but obviously a
slower but sane implementation of exception traps could be built on top of
the existing machinery. With a bit of duct-tape, perturb could no doubt be
combined with quickcheck to prove some relatively interesting properties.
Matt and I did this mainly out of curiosity and to fill a gap, as neither of
us has a real need for this sort of control over IEEE state at the moment.
As such, I don't have a good idea of what is good or bad in the API or could
be more convenient. However, I'd urge folks with an itch to scratch to give
this all a try and maybe provide some feedback, use-cases, implementations
of algorithms that need this sort of thing, of course patches, etc.
[1]
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ieee-utils-0.4.0
Cheers,
Sterl.
On Fri, Oct 17, 2008 at 11:19 AM, Ariel J. Birnbaum
It is an interesting question: can IEEE floating point be done purely while preserving the essential features. I've not looked very far so I don't know how far people have looked into this before. Not sure. My doubts are mainly on interference between threads. If a thread can keep its FP state changes 'local' then maybe it could be done. I still think FP operations should be combined in a monad though --- after all, they depend on the evaluation order.
Haskell currently only supports a subset of the IEEE FP api. One can assume that that's mainly because the native api for the extended features is imperative. But need it be so?
Rounding modes sound to me like an implicit parameter. Traps and exception bits sound like the implementation mechanism of a couple standard exception handling strategies. The interesting thing here is that the exception handling strategy is actually an input parameter. Reader? =)
So part of the issue is a functional model of the FP api but the other part is what compiler support would be needed to make a functional api efficient. For example if the rounding mode is an implicit parameter to each operation like + - * etc then we need some mechanism to make sure that we don't have to actually set the FP rounding mode before each FP instruction, but only at points where we know it can change, like passing a new value for the implicit parameter, or calling into a thunk that uses FP instructions. This one seems like a tough one to figure. Again, I'd vouch for a solution like STM --- composition of FP operations is allowed at a certain level (maybe enforcing some settings to remain constant here), while it takes a stronger level to connect them to their surroundings.
There's also the issue that if the Float/Double operations take an implicit parameter, can they actually be instances of Num? Is that allowed? I don't know. Technically I guess they could, just like (Num a) => (b->a) can be made an instance. It would look more like State though, IMO. Or Cont. Doesn't even look like Oleg-fu is needed.
Should they? That's a horse of a different colour. There are certain properties most programmers come to expect of such instances (regardless of whether the Report demands them or not), such as associativity of (+) and (==) being an equivalence that break miserably for floating point.
Floating point is a hairy area for programing in general, but I think it's also one where Haskell can shine with an elegant, typesafe model.
-- Ariel J. Birnbaum _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe