[Haskell-cafe] Crash in GHCI - what is the correct behavior here?
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
>> 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
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> let f x = let p = x*x in let p = x*p in p
Prelude> f 7
C:\Documents and Settings\Zach>
That's it. This is on Windows XP Service Pack 2.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe