Re: [Haskell-cafe] Monadic Floating Point [was: Linking and unsafePerformIO]
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 [EMAIL PROTECTED] wrote: 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 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monadic Floating Point [was: Linking and unsafePerformIO]
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
Re: [Haskell-cafe] Monadic Floating Point [was: Linking and unsafePerformIO]
On 2008 October 16 Thursday, Duncan Coutts wrote: On Thu, 2008-10-16 at 01:24 +0200, Ariel J. Birnbaum wrote: Floating point operations, at least by IEEE754, depend on environmental settings like the current rounding mode. They may modify state, like the sticky bits that indicate an exception occurred. It is an interesting question: can IEEE floating point be done purely while preserving the essential features. The trouble is that the best numerical algorithms have been written using the imperative-style IEEE operations for more than 20 years. If Haskell had a floating point monad, then those algorithms could be coded in Haskell. But that doesn't seem like an interesting and fruitful approach. Haskell can access those algorithms using FFI. The test of making IEEE floating point accessible in pure Haskell code is whether it stirs any interest in the numerical analysis community. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monadic Floating Point [was: Linking and unsafePerformIO]
On Wednesday 15 October 2008 05:21:04 John Dorsey wrote: Should all floating point numerals be in the IO Monad? I'm deviating from the thread's topic, but I tend to agree with this one. Maybe not IO directly, but some kind of STM-style monad, at least (that is, FP operations are composable but ultimately they must be evaluated in IO). Floating point operations, at least by IEEE754, depend on environmental settings like the current rounding mode. They may modify state, like the sticky bits that indicate an exception occurred. They may jump nonlocally if a trap handler has been enabled. None of these help in making an expression like (a + b) + c == a + (b + c) :: Bool any more referentially transparent than getChar : getChar : [] :: [Char] would be if it was legal. Anyway, enough rant for tonight. Sorry for the hijack. We now resume our regular transmissions. -- Ariel J. Birnbaum ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monadic Floating Point [was: Linking and unsafePerformIO]
On Thu, 2008-10-16 at 01:24 +0200, Ariel J. Birnbaum wrote: On Wednesday 15 October 2008 05:21:04 John Dorsey wrote: Should all floating point numerals be in the IO Monad? I'm deviating from the thread's topic, but I tend to agree with this one. Maybe not IO directly, but some kind of STM-style monad, at least (that is, FP operations are composable but ultimately they must be evaluated in IO). Floating point operations, at least by IEEE754, depend on environmental settings like the current rounding mode. They may modify state, like the sticky bits that indicate an exception occurred. They may jump nonlocally if a trap handler has been enabled. 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. 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. 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. 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. Duncan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe