[Haskell-cafe] Lazy in either argument?

Lennart Augustsson lennart at augustsson.net
Thu Jul 26 18:34:37 EDT 2007


The non-termination is (probably) due to the fact that you can have
uninterruptible threads in ghc.
If a thread never allocates it will never be preempted. :(

  -- Lennart

On 7/24/07, Dan Weston <westondan at imageworks.com> wrote:
>
> I am trying to get my feet wet with Haskell threads with the following
> problem, inspired by a recent post
> (http://www.haskell.org/pipermail/haskell-cafe/2007-July/029408.html)
> saying that:
>
> > Since there's no way to have a function be lazy in both arguments, the
> > implicit convention is to make functions strict in the first arguments
> > and, if applicable, lazy in the last arguments. In other words, the
> > convention is
> >
> >   True || _|_ = True   but not  _|_ || True = True
> >
> >   1 + _|_ = Succ _|_   but not  _|_ + 1 = Succ _|_
> >
> > Regards,
> > apfelmus
>
> Maybe not lazy in both arguments, but how about lazy in either argument?
>
> The idea is to fork a thread for each of the two functions, (||) and
> flip (||), pick the winner, then kill off both threads. I can wrap this
> up in a pure function using unsafePerformIO (given the proof obligation
> that the results of both threads will always be equal where both are
> defined).
>
> The code below seems to work, except for the following problems:
>
> 1) Commenting out the type annotation f :: Bool makes the program hang
> 2) If I replace f = f by f = undefined, I get an annoying print of
> "LazyOr: Prelude.undefined" before it returns the correct value.
>
> Does anyone know why the type annotation is needed in #1, and/or how to
> suppress the error message in #2?
>
> Dan Weston
>
> -----------------------------------------------------------
> import Control.Monad(when)
> import Control.Concurrent(forkIO,killThread)
> import Control.Concurrent.Chan(newChan,readChan,writeChan,isEmptyChan)
> import Foreign(unsafePerformIO)
>
> f :: Bool
> f = f
>
> main = putStrLn . show $ lazyBinaryOp (||) f True
>
> lazyBinaryOp p x y = unsafePerformIO $ do
>      c  <- newChan
>      p2 <- forkIO (lazyBinaryOpThread c p x y)
>      p1 <- forkIO (lazyBinaryOpThread c p y x)
>      z  <- readChan c
>      killThread p1
>      killThread p2
>      return z
>
>    where
>
>      lazyBinaryOpThread c p x y = do
>        case (p x y) of True  -> writeChan c True
>                        False -> writeChan c False
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20070726/d8c13907/attachment.htm


More information about the Haskell-Cafe mailing list