
On Sun, Jan 28, 2007 at 07:16:16PM +0000, Chris Kuklewicz wrote:
Iavor Diatchki wrote:
Hello, The "packCString" function (and other similar functions) in the ByteString library break referential transperancy, which is one of the big selling points of Haskell (and its libraries). Here is an example:
main = do x <- newCString "Hello" let s = packCString x h1 = B.head s print s -- print h1 poke x (toEnum 97) print s let h2 = B.head s print h1 print h2 Output: "Hello" "aello" 97 97
This is already confusing because the "pure" value 's' has magically changed. Also notice that the evaluation order of the program affects the output. If we include the commented out statement (which forces h1 to be evaluated earlier) the output becomes: "Hello" 72 "aello" 72 97
It gets more fun: import Foreign.C.String import Data.ByteString import Control.Exception shouldBePure :: CString -> () shouldBePure str = packMallocCString str `seq` () main = do x <- newCString "Hello" evaluate $ shouldBePure x evaluate $ shouldBePure x -- force a GC evaluate $ Prelude.reverse [0..] --> stefan@stefans:/tmp$ ./X *** glibc detected *** double free or corruption (fasttop): 0x08086628 *** Aborted Now what if GHC did more CSE... <shudder>