V.Liepelt V.Liepelt at kent.ac.uk
Wed Jan 2 12:34:58 UTC 2019

```False <= _ = True
_ <= y = y

Yeah, that’s what I was thinking (in fact this is how I hit this in the first place—I was using `(<=)` as a quick and dirty logical implication operator and was surprised to hit `undefined` even though the precondition was False!)

Note that even with this definition, "undefined <= True = undefined" so strictness is now not symmetric.

Isn’t “asymmetry” the whole point of laziness? Consider `(||)`.

Note "fromEnum" here is zero cost, and there is no branch. Checking the left hand branch for false first would require a branch that would possibly hit performance. This probably isn't worth slowing down this function just so it's lazy in it's right argument (but as a gotcha now, still strict in it's left argument).

Yes, comparison on constants may happen to be faster on a concrete architecture. Thanks, I hadn’t considered this. However this assumes that both arguments are already evaluated, which of course will require branching unless you happen to know the second argument at compile time, for which case we might want to have a rewrite rule for the more efficient implementation. But it feels wrong to make architectural considerations leak into the standard library when this isn’t really necessary.

V

How would you define Ord on Bools? Like so?

False <= _ = True
_ <= y = y

Note that even with this definition, "undefined <= True = undefined" so strictness is now not symmetric.

Also, as bool are implemented as just an int of some sort (presumably 0 and 1), the strict definition allows the following implementation in effect:

Note "fromEnum" here is zero cost, and there is no branch. Checking the left hand branch for false first would require a branch that would possibly hit performance. This probably isn't worth slowing down this function just so it's lazy in it's right argument (but as a gotcha now, still strict in it's left argument).

On Wed, Jan 2, 2019 at 10:50 PM V.Liepelt <V.Liepelt at kent.ac.uk<mailto:V.Liepelt at kent.ac.uk>> wrote:
> The implementation of the Ord instance for Bool is derived

So my argument would be—doesn’t this mean that we need to do cleverer deriving or at least have a hand-written instance?

> As for the justification, perhaps it's too much of a special case for only
> one value of an enumeration to compare to undefined without crashing

This is not just about crashing. (I’m using `undefined` as a way of making strictness explicit.) `False >= veryExpensiveComputation` should return `True` immediately without any unnecessary computation.

Also it doesn’t seem like a special case: this makes sense for any partially ordered Type with a top and/or bottom element.

> perhaps it inhibits optimisation opportunities.

That doesn’t seem very likely to me, I would rather think the contrary (see above): doing unnecessary work can hardly make a program run faster.

V

> On 2 Jan 2019, at 11:37, Tom Ellis <tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk<mailto:tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk>> wrote:
>
> On Wed, Jan 02, 2019 at 09:47:15AM +0000, V.Liepelt wrote:
>> I am surprised to find that `False <= undefined = undefined`.
>>
>> What justifies (<=) to be strict in both arguments?
>
> The implementation of the Ord instance for Bool is derived, as you can see
> here:
>
>
> As for the justification, perhaps it's too much of a special case for only
> one value of an enumeration to compare to undefined without crashing, and
> perhaps it inhibits optimisation opportunities.
>
> Tom
> _______________________________________________
> To (un)subscribe, modify options or view archives go to:
> Only members subscribed via the mailman list are allowed to post.

_______________________________________________