elm / compiler

Compiler for Elm, a functional language for reliable webapps.
https://elm-lang.org/
BSD 3-Clause "New" or "Revised" License
7.52k stars 661 forks source link

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

Open coreygirard opened 10 months ago

coreygirard commented 10 months ago

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.

Additional Details

bug : Float
bug =
    1
        |> (\x ->
                x
                    * 1.5
                    + modBy x 2
           )
github-actions[bot] commented 10 months ago

Thanks for reporting this! To set expectations:

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

lydell commented 10 months ago

What is the root cause, according to you?

coreygirard commented 10 months ago

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.