elm/compiler

Error message should be more informative when integer literal is being used as both integer and float

coreygirard opened this issue · 3 comments

Quick Summary: The error message when an integer literal is being used as both integer and float doesn't point out the root cause.

SSCCE

Source

bug : ( Float, Int )
bug =
    1
        |> (\x ->
                ( x * 1.5
                , modBy x 2
                )
           )

Expected output

Error message explaining that the literal is being simultaneously used as both an int and a float.

Received output

-- TYPE MISMATCH -------------------------------------------------- src/Main.elm

The 1st argument to `modBy` is not what I expect:

119|                 , modBy x 2
                             ^
This `x` value is a:

    Float

But `modBy` needs the 1st argument to be:

    Int

Note: Read <https://elm-lang.org/0.19.1/implicit-casts> to learn why Elm does
not implicitly convert Ints to Floats. Use toFloat and round to do explicit
conversions.
  • Elm: 0.19.1
  • Browser: N/A
  • Operating System: MacOS 12.6

Additional Details

  • Behavior does not require tuple; the following more verbose version triggers the same behavior:
bug : Float
bug =
    1
        |> (\x ->
                x
                    * 1.5
                    + modBy x 2
           )

Thanks for reporting this! To set expectations:

  • Issues are reviewed in batches, so it can take some time to get a response.
  • Ask questions in a community forum. You will get an answer quicker that way!
  • If you experience something similar, open a new issue. We like duplicates.

Finally, please be patient with the core team. They are trying their best with limited resources.

What is the root cause, according to you?

I'd say from a user standpoint, the root cause is that a thing which is slightly ambiguous/flexible by design (integer literal) is attempting to be subsequently used as two different types.

Hitting this error message and using it for debugging is IMHO significantly more difficult than the usual incredibly helpful Elm debugging experience.

For example, when I hit this in my project, I then looked at the place the variable was initialized and saw it was (the equivalent of) x = 1. So I figured "okay, the type matches, so that's not it". Then I went off on a fruitless and unnecessary debugging dead end.

I think the difficult part is that this requires examination of 3+ code locations (the variable initialization and the two or more locations where it is used), which may not be particularly close to one another, and may not be immediately obvious. I feel one of the strengths of Elm is precisely the lack of spooky-action-at-a-distance like this.