unsafeInterleaveIO, lazyness and sharing

Hello, Haskell is non-strict but not necessarily lazy. So it’s possible that an expression is reduced to WHNF although it is not used yet. Could this “early reduction” also happen to outputs of unsafeInterleaveIO actions (which might trigger the action too early)? While I’d expect those outputs to be evaluated lazily (reduced as late as possible), I cannot find anything in the docs that guarantees this. In addition, I’d like to know whether unsafeInterleaveIO outputs are guaranteed to be evaluated at most once so that the “interleaved action” is executed at most once. Again, I suppose that this is the case while I cannot find a guarantee for it. Best wishes, Wolfgang

Wolfgang,
Haskell is non-strict but not necessarily lazy. So it's possible that an expression is reduced to WHNF although it is not used yet. Could this early reduction also happen to outputs of unsafeInterleaveIO actions (which might trigger the action too early)? While I'd expect those outputs to be evaluated lazily (reduced as late as possible), I cannot find anything in the docs that guarantees this.
"unsafeInterleaveIO allows IO computation to be deferred lazily. When passed a value of type IO a, the IO will only be performed when the value of the a is demanded. This is used to implement lazy file reading, see hGetContents." http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html... Is this the kind of guarantee you're looking for? I'd bet against getting any decent durable, portable guarantees for any unsafe* functions in Haskell; but the above behavioral description may be strong enough to suit you.
In addition, I'd like to know whether unsafeInterleaveIO outputs are guaranteed to be evaluated at most once so that the interleaved action is executed at most once. Again, I suppose that this is the case while I cannot find a guarantee for it.
I'd be surprised if an implementation didn't have that behavior. I'd also be wary of anyone claiming to guarantee it, beyond compiler X version Y. John Dorsey

On Wed, 2008-08-27 at 01:48 +0200, Wolfgang Jeltsch wrote:
Hello,
Haskell is non-strict but not necessarily lazy. So it’s possible that an expression is reduced to WHNF although it is not used yet. Could this “early reduction” also happen to outputs of unsafeInterleaveIO actions (which might trigger the action too early)? While I’d expect those outputs to be evaluated lazily (reduced as late as possible), I cannot find anything in the docs that guarantees this.
In addition, I’d like to know whether unsafeInterleaveIO outputs are guaranteed to be evaluated at most once so that the “interleaved action” is executed at most once. Again, I suppose that this is the case while I cannot find a guarantee for it.
I believe ghc does provide the behaviour you want, almost. I say almost because there is an issue with concurrency. In early versions of ghc's smp implementation it was easy to set up an experiment where two threads would pull on the result of hGetContents and observe different results. This was because different threads could occasionally enter an IO thunk simultaneously. This is now fixed but I understand the fix is not an absolute guarantee. This concurrency difference is the distinction between unsafeInterleaveIO and unsafeDupableInterleaveIO. unsafeDupableInterleaveIO itself is not currently documented but the difference is the same as for unsafeDupablePerformIO which is documented as: This version of 'unsafePerformIO' is slightly more efficient, because it omits the check that the IO is only being performed by a single thread. Hence, when you write 'unsafeDupablePerformIO', there is a possibility that the IO action may be performed multiple times (on a multiprocessor), and you should therefore ensure that it gives the same results each time. Though as I said, the check that the IO is only being performed by a single thread is apparently not an absolute guarantee. The details of why exactly I do not fully understand. If you want a full explanation ask Simon Marlow. Duncan
participants (3)
-
Duncan Coutts
-
John Dorsey
-
Wolfgang Jeltsch