4
votes

Function signature clearly states that it should return a Bool so why is the function returning 96? What is more, compiler thinks that 96 is actually a Bool. Is this a bug?

> isLeapYear year =\
|       (modBy 4 year == 0) && (modBy 100 year /= 0) || (modBy 400 year == 0)
<function> : Int -> Bool

> isLeapYear 1996
96 : Bool

It seems to work sometimes though:

> isLeapYear 2000
True : Bool
> isLeapYear 1800
False : Bool
1
Yea, it definitely looks like a bug and I'm able to reproduce it using the /= operator against a 0 on either side. For example, 1 /= 0 and 0 /= 1 both yield 1 : Bool while 1 /= 2 yields the expected True : BoolChad Gilbert
Probably a repl bug rather than a compiler bug though. I doubt an issue like this in actual compiled code would have gone unnoticed for so long.glennsl
It's an issue in a compiled code, just checked by printing it into a webapp. It is also in the elm-test output.frost
Here is an Ellie example that shows this is a bug in compiled code. It prints two list of booleans, the first modding by 0 and showing an integer instead of a bool, and the second list modding by 1 and showing a boolean appropriately. I would wager the problem involves Debug.print since it is not just in the REPL.Chad Gilbert

1 Answers

7
votes

This is a compiler bug which I filed last year and which has now been fixed.

It affects only the /= operator when one argument is 0: replacing (modBy 100 year /= 0) with (not (modBy 100 year == 0)) will work around the problem.

The bug has been fixed in the source repository, but I don't know when the fix will be released.