The non-termination is (probably) due to the fact that you can have uninterruptible threads in ghc.<br>If a thread never allocates it will never be preempted. :(<br><br>&nbsp; -- Lennart<br><br><div><span class="gmail_quote">On 7/24/07, 
<b class="gmail_sendername">Dan Weston</b> &lt;<a href="mailto:westondan@imageworks.com">westondan@imageworks.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I am trying to get my feet wet with Haskell threads with the following<br>problem, inspired by a recent post<br>(<a href="http://www.haskell.org/pipermail/haskell-cafe/2007-July/029408.html">http://www.haskell.org/pipermail/haskell-cafe/2007-July/029408.html
</a>)<br>saying that:<br><br> &gt; Since there&#39;s no way to have a function be lazy in both arguments, the<br> &gt; implicit convention is to make functions strict in the first arguments<br> &gt; and, if applicable, lazy in the last arguments. In other words, the
<br> &gt; convention is<br> &gt;<br> &gt;&nbsp;&nbsp; True || _|_ = True&nbsp;&nbsp; but not&nbsp;&nbsp;_|_ || True = True<br> &gt;<br> &gt;&nbsp;&nbsp; 1 + _|_ = Succ _|_&nbsp;&nbsp; but not&nbsp;&nbsp;_|_ + 1 = Succ _|_<br> &gt;<br> &gt; Regards,<br> &gt; apfelmus<br><br>Maybe not lazy in both arguments, but how about lazy in either argument?
<br><br>The idea is to fork a thread for each of the two functions, (||) and<br>flip (||), pick the winner, then kill off both threads. I can wrap this<br>up in a pure function using unsafePerformIO (given the proof obligation
<br>that the results of both threads will always be equal where both are<br>defined).<br><br>The code below seems to work, except for the following problems:<br><br>1) Commenting out the type annotation f :: Bool makes the program hang
<br>2) If I replace f = f by f = undefined, I get an annoying print of<br>&quot;LazyOr: Prelude.undefined&quot; before it returns the correct value.<br><br>Does anyone know why the type annotation is needed in #1, and/or how to
<br>suppress the error message in #2?<br><br>Dan Weston<br><br>-----------------------------------------------------------<br>import Control.Monad(when)<br>import Control.Concurrent(forkIO,killThread)<br>import Control.Concurrent.Chan
(newChan,readChan,writeChan,isEmptyChan)<br>import Foreign(unsafePerformIO)<br><br>f :: Bool<br>f = f<br><br>main = putStrLn . show $ lazyBinaryOp (||) f True<br><br>lazyBinaryOp p x y = unsafePerformIO $ do<br>&nbsp;&nbsp;&nbsp;&nbsp; c&nbsp;&nbsp;&lt;- newChan
<br>&nbsp;&nbsp;&nbsp;&nbsp; p2 &lt;- forkIO (lazyBinaryOpThread c p x y)<br>&nbsp;&nbsp;&nbsp;&nbsp; p1 &lt;- forkIO (lazyBinaryOpThread c p y x)<br>&nbsp;&nbsp;&nbsp;&nbsp; z&nbsp;&nbsp;&lt;- readChan c<br>&nbsp;&nbsp;&nbsp;&nbsp; killThread p1<br>&nbsp;&nbsp;&nbsp;&nbsp; killThread p2<br>&nbsp;&nbsp;&nbsp;&nbsp; return z<br><br>&nbsp;&nbsp; where<br><br>&nbsp;&nbsp;&nbsp;&nbsp; lazyBinaryOpThread c p x y = do
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case (p x y) of True&nbsp;&nbsp;-&gt; writeChan c True<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; False -&gt; writeChan c False<br><br>_______________________________________________<br>Haskell-Cafe mailing list<br><a href="mailto:Haskell-Cafe@haskell.org">
Haskell-Cafe@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br></blockquote></div><br>