On Sat, 2009-05-23 at 13:31 -0400, Mario Blažević wrote: > >>> You could probably see exactly what's happening in > >>> more detail by going through the Core output. > >> > >> Thank you, this advice helped. The Core output indicates > >> that function `test' evaluates the arguments to > >> `parallelize' before it calls it. In other words, the > >> call to `parallelize' is optimized as a strict function > >> call -- which it is. The problem is that this > >> optimization evaluates the arguments sequentially. > >> Compiling with optimizations turned off regains the > >> parallel execution. > >> > >> I guess I will report this as a GHC bug. Or is it a > >> feature request? > > > > As Duncan suggessted, try with GHC head (grab a snapshot). `par` et al > > are much improved. > > I already have, with the snapshot from 21st of April. It behaves the same > as 6.8.2, except it runs for twice as long. > > I'd like to take back a part of what I said before, though: `parallelize' > should > be strict only in its second argument.
parallelize a b = a `par` (b `pseq` (a, b)) GHC infers that strictness of parallelize. It thinks that it is lazy in both args (you can check this yourself using ghc --show-iface). That's because the definitions of par and pseq use the function 'lazy': -- The reason for the strange "lazy" call is that it fools -- the compiler into thinking that pseq and par are non-strict in -- their second argument (even if it inlines pseq at the call site). -- If it thinks pseq is strict in "y", then it often evaluates -- "y" before "x", which is totally wrong. pseq x y = x `seq` lazy y par x y = case (par# x) of { _ -> lazy y } So GHC thinks that par is lazy in both arguments, while it thinks pseq is strict in the first and lazy in the second. > Its strictness in the first argument should be the same as with `par`. Yes, which it is. > Even though `parallelize x y' always evaluates both x and y, Be careful about what you mean. Yes, it starts the evaluation of x in parallel with y, but that does not mean it is strict in x, as you notice with your example of undefined below. > the following test works fine with optimizations even if `parallelize' > is imported: > > main = putStrLn (snd $ parallelize undefined "Hello, World!") > > So the function is not strict, and I don't understand why GHC should evaluate > the > arguments before the call. Right, it's lazy in the first and strict in the second argument. As far as I can see we have no evidence that is is evaluating anything before the call. > Does anybody know of a pragma or another way to make a function *non-strict* > even > if it does always evaluate its argument? In other words, is there a way to > selectively disable the strictness optimization? Yes, which is what pseq and par already do. If there's a bug, we need to reproduce it and report it. I cannot reproduce it. Duncan _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe