> During debugging my experimental code I found a following problem:
> when my module is loaded following occurs:
>
> "
> StrictMemo> test
> rootVal = memo: [(Ext:*:1:*:Ext:*:2,memo: [(Ext:*:1,doExt( 1 )
> 1),(Ext:*:1:*:Ext:*:2,
> Program error: {_Gc Black Hole}
> "
I haven't had a chance to run the code yet - but let me explain what a
black hole is.
The simplest black hole you can write is this:
let x = x in x
Basically it's an infinite loop.
However, it happens to be a kind of infinite loop which the evaluator
is able to detect pretty easily (at runtime) because the value of a
variable is dependent on itself and so the evaluator can easily spot
that it's trying to evaluate a variable that is already in the
process of being evaluated. Hugs calls it a "_Gc Black Hole"
because it only checks for infinite loops of this kind during
garbage collection. (The same goes for GHC.) It's safe to put off
the check until GC time because if it's in an infinite loop,
it's a safe bet it's going to GC a few times before it finishes :-)
Given that your program is messing around with laziness/strictness,
it seems pretty likely that this is a key part of the problem
(and not some random bug in the garbage collector, say).
So, why do GHC and Hugs give different results?
Probably because we both use slightly modified versions of the
Prelude with subtly different strictness properties.
Maybe Hugs version of some standard function is slightly stricter
than it should be?
Maybe GHC's version of a function is slightly lazier than it
should be?
Maybe GHC has some optimisations which sometimes make functions
evaluate their arguments in different orders?
I'll try to have a look later today - but (unless some obvious Hugs bug
turns up) I think you should take it as a warning that you're
on very thin ice and should hunt for where it's thicker.
eg you might avoid using standard prelude functions and
write your own instead so that you know exactly what they do.
A
as