# [Haskell-cafe] Crash in GHCI - what is the correct behavior here?

Zachary Turner divisortheory at gmail.com
Thu Mar 19 00:55:01 EDT 2009

```On Wed, Mar 18, 2009 at 11:46 PM, Luke Palmer <lrpalmer at gmail.com> wrote:

> 2009/3/18 Zachary Turner <divisortheory at gmail.com>
>
>> Basically just learning haskell, I would have posted this in the beginners
>> list but since it involves a segfault of GHCI, I figured it might be worth
>> posting here.
>>
>> I was trying to get a good understanding of local variable scoping issues,
>> so I tried the following:
>>
>> f :: (Num a) => a -> a
>> f x =
>>     let p = x*x
>>     in
>>         let p = x*p
>>         in p
>>
>> I have some background in ML, which led me to believe that what should
>> happen here is that the function would return x^3.  Instead, GHCI just
>> completely terminates, I guess with a segfault.  What's the "correct"
>> behavior here?  Should it even compile?  I understand that you can't
>> redefine the same symbol twice in the same scope, so I tried this
>> specifically to see what would happen if you defined the same variable again
>> in a nested scope.  I thought it would just shadow the original declaration,
>> while still using the original p to calculate the value of the new p.  I
>> don't think the problem is the re-declaration of the same symbol in a nested
>> scope (although if someone could clarify that would be nice), but rather the
>> fact that I've attempted to use the previous declaration of p in defining
>> the new declaration of p.
>
>
> You are correct that the inner p shadows the outer p.  However, you are
> incorrect that "p" on the right side of the inner definition is the outer p
> (man this is hard to talk about).  Lets in Haskell are recursive, so your
> program is equivalent to:
>
> f x = let p = x*p in p
>
> I'm going to do a little domain theory now, because I'm in the mood :-).
> So p is the least value which satisfies the equation p = x*p.  For most
> numeric types, (*) is strict in its right argument, so _|_ = x*_|_.  And in
> fact this is the equation we had to satisfy, and there is no value less than
> _|_, so p = _|_.
>
> So, f x = _|_. (an infinite loop)
>
> I love Haskell so much.  T'aint no language more precise.
>
> Anyway, there are various ways that Haskell handles bottom.  If you're
> seeing ghci immediately exit, you're probably observing "black hole
> detection", in which ghci prints <loop> to inform you you have an infinite
> loop instead of actually looping forever.  There are certain cases where
> this can be done.
>
> If that's not consistent with what you observed, more details please!
> Including version, OS, compiler flags, and transcript.  It might indeed be a
> bug :-)
>

Regarding the "black hole detection", is GHCI supposed to exit after
printing <loop>?  Or is just supposed to print <loop> then return to a GHCI
prompt?  Here's a transcript:

C:\Documents and Settings\Zach>ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help