
On Mon, Jan 6, 2014 at 9:33 PM, Courtney Robinson
I've found this example.
An example of something you should not do; it is very fragile. Most notably, if the compiler decides to inline counter then you no longer have a single IORef. (It will work in ghci/runhaskell, which does not have an optimizer.) I have two things I'm failing to see about it.
1) Why doesn't counter return a newIORef with value 0, every time getUnique is called there by producing a value of 1 no matter how often getUnique is called? Is this this because it returns an IORef so counter just becomes bound to the value it first returns and it's not evaluated again and the IORef is just returned, or something else?
Anything given a name and no parameters (and not polymorphic; see the monomorphism restriction) is potentially shared. The unsafePerformIO would be run only once and its result remembered and shared between all uses --- if you're lucky. The compiler is allowed to do anything it wants as long as it would have the same behavior; but because you hid an effect behind unsafePerformIO, thereby telling the compiler that it is a pure value that it is free to remember or recompute as it sees fit, the compiler's idea of what constitutes "the same behavior" is likely to be different from yours. 2) Why does the lambda return a tuple and why does the example return the
same value in both positions i.e. (y,y)? The only thing I could think of is because the name has "atomic" that the values in the tuple is being used for some sort of compare and swap,CAS.
One value is the return value of atomicModifyIORef; the other is the new value to be stored. You could think of this as the Haskell version of the preincrement/postincrement operators in some languages. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net