# [Haskell-cafe] GHC bug? Let with guards loops

Felipe Almeida Lessa felipe.lessa at gmail.com
Tue Jul 9 19:23:25 CEST 2013

```Well, you could use p's type for something.

let x | foo (undefined `asTypeOf` x) = 3
foo _ = True
in x

Arguably not very useful.  It seems to me that the most compelling
rationale is being consistent with the cases where, instead of being a
data type, p is a function.  Even so most of the time you won't be
recursing on the guard.  But, since you could use something from the
where clause on the guard, and we certainly won't be restricting
recursing on the where clause, it also seems compelling to allow
recursion on the guard.

My 2 centavos, =)

On Tue, Jul 9, 2013 at 2:12 PM, Andreas Abel <andreas.abel at ifi.lmu.de> wrote:
> Thanks, Dan and Roman, for the explanation.  So I have to delete the
> explanation "non-recursive let = single-branch case" from my brain.
>
> I thought the guards in a let are assertations, but in fact it is more like
> an if.  Ok.
>
> But then I do not see why the pattern variables are in scope in the guards
> in
>
>   let p | g = e
>
> The variables in p are only bound to their values (given by e) if the guard
> g evaluates to True.  But how can g evaluate if it has yet unbound
> variables?  How can ever a pattern variable of p be *needed* to compute the
> value of the guard?  My conjecture is that it cannot, so it does not make
> sense to consider variables of g bound by p.  Maybe you can cook up some
> counterexample.
>
> I think the pattern variables of p should not be in scope in g, and
> shadowing free variables of g by pattern variables of p should be forbidden.
>
> Cheers,
> Andreas
>
> On 09.07.2013 17:05, Dan Doel wrote:> The definition
>
>>
>>      Just x | x > 0 = Just 1
>>
>> is recursive. It conditionally defines Just x as Just 1 when x > 0 (and
>> as bottom otherwise). So it must know the result before it can test the
>> guard, but it cannot know the result until the guard is tested. Consider
>> an augmented definition:
>>
>>      Just x | x > 0  = Just 1
>>             | x <= 0 = Just 0
>>
>> What is x?
>
> On 09.07.2013 17:49, Roman Cheplyaka wrote:
>>
>> As Dan said, this behaviour is correct.
>>
>> The confusing thing here is that in case expressions guards are attached
>> to the patterns (i.e. to the lhs), while in let expressions they are
>> attached to the rhs.
>>
>> So, despite the common "Just x | x > 0" part, your examples mean rather
>> different things.
>>
>> Here's the translation of 'loops' according to the Report:
>>
>>    loops =
>>      let Just x =
>>        case () of
>>          () | x > 0 -> Just 1
>>      in x
>>
>> Here it's obvious that 'x' is used in the rhs of its own definition.
>>
>> Roman
>>
>> * Andreas Abel <andreas.abel at ifi.lmu.de> [2013-07-09 16:42:00+0200]
>>>
>>> Hi, is this a known bug or feature of GHC (7.4.1, 7.6.3)?:
>>>
>>> I got a looping behavior in one of my programs and could not explain
>>> why.  When I rewrote an irrefutable let with guards to use a case
>>> instead, the loop disappeared.  Cut-down:
>>>
>>>    works = case Just 1 of { Just x | x > 0 -> x }
>>>
>>>    loops = let Just x | x > 0 = Just 1 in x
>>>
>>> works returns 1, loops loops.  If x is unused on the rhs, the
>>> non-termination disappears.
>>>
>>>    works' = let Just x | x > 0 = Just 1 in 42
>>>
>>> Is this intended by the Haskell semantics or is this a bug?  I would
>>> have assumed that non-recursive let and single-branch case are
>>> interchangeable, but apparently, not...
>>>
>>> Cheers,
>>> Andreas
>>>
>>> --
>>> Andreas Abel  <><      Du bist der geliebte Mensch.
>>>
>>> Theoretical Computer Science, University of Munich
>>> Oettingenstr. 67, D-80538 Munich, GERMANY
>>>
>>> andreas.abel at ifi.lmu.de
>>> http://www2.tcs.ifi.lmu.de/~abel/
>>>
>>> _______________________________________________
>>
>>
>
>
> --
> Andreas Abel  <><      Du bist der geliebte Mensch.
>
> Theoretical Computer Science, University of Munich
> Oettingenstr. 67, D-80538 Munich, GERMANY
>
> andreas.abel at ifi.lmu.de
> http://www2.tcs.ifi.lmu.de/~abel/
>
> _______________________________________________