[Haskell-cafe] GHC bug? Let with guards loops
Dan Doel
dan.doel at gmail.com
Tue Jul 9 19:56:42 CEST 2013
With pattern guards, it's difficult to say whether it is never 'useful' to
have things like the following work:
C x | C' y z <- f x = ...
But I'd also shy away from changing the behavior because it causes a lot of
consistency issues. In
let
f <vs1> | gs1 = es1
h <vs2> | gs2 = es2
...
we have that f and h are in scope in both gs1 and gs2. Does it make sense
to call f in gs1? It's easy to loop if you do. So should f not be in scope
in gs1, but h is, and vice versa for gs2? But they're both in scope for es1
and es2?
And if we leave the above alone, then what about the case where there are
no <vs>? Is that different? Or is it only left-hand patterns that get this
treatment?
Also, it might have some weird consequences for moving code around. Like:
let Just x | x > 0 = Just 1
let Just x | y > 0 = Just 1
y = x
let Just x | b = Just 1
where b = x > 0
let Just x | b = Just 1
b = x > 0
These all behave the same way now. Which ones should change?
If Haskell had a non-recursive let, that'd probably be a different story.
But it doesn't.
On Tue, Jul 9, 2013 at 1: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/ <http://www2.tcs.ifi.lmu.de/~abel/>
>>>
>>> ______________________________**_________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org
>>> http://www.haskell.org/**mailman/listinfo/haskell-cafe<http://www.haskell.org/mailman/listinfo/haskell-cafe>
>>>
>>
>>
>
> --
> 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/ <http://www2.tcs.ifi.lmu.de/~abel/>
>
> ______________________________**_________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/**mailman/listinfo/haskell-cafe<http://www.haskell.org/mailman/listinfo/haskell-cafe>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20130709/29727572/attachment.htm>
More information about the Haskell-Cafe
mailing list