Why does scientific notation break the range function?

It’s not about whether a few experts on this forum can understand the error message, it’s about what will be best understood by most users.

The current error message:

  1. fails to identify which line the error occurs on,
  2. fails to identify which function is causing the error,
  3. poorly communicates what’s actually causing the error, and
  4. does not offer the user any constructive solutions.

I encourage you to read the current error message aloud to a spouse or roommate, or get Google to read it aloud to you. Then compare against my suggested rewrite. Here’s the comparison:

ERROR: TypeError: in keyword argument length, expected Union{Nothing, Integer}, got a value of type Float64.
. . . 
ERROR in range(): Keyword argument length was entered as type Float64, but should be of type Integer.

I am of course very biased, but it’s hard to believe that any neutral party would say the current error message is better in any way, compared to my suggested rewrite. Are there some merits to the current error message that I’m not understanding?

9 Likes

The current message has the advantage that it doesn’t lie about the expected type.

7 Likes

I would prefer:
TypeError in range(): Keyword argument length was entered as type Float64, but should be a subtype of Union{Nothing,Integer}.
starting with TypeError i already know that one function has an incorrect input. The ERROR: TypeError is superfluous. on the type suggestion, Union{Nothing,Integer} is not a concrete type, so the error message should explicitly say that the input is not a subtype, instead of is not an expected type.

9 Likes

This is a problem of the environment in which you’re coding. When you’re executing scripts, Julia does point out the line that caused the error. This might be solved by the plugin for VS Code, but I don’t know if it is possible or feasible (hope it is).

Think this could be changed, as pointed out by @trahflow here. I think is worth filling an issue. :slight_smile:

I disagree with this, as it does say that you’re passing the wrong type to the argument. That the expected type Union{Nothing, Integer} is not trivial to understand coming from another languages is not a problem of Julia. I would argue that this is something almost every user will need to learn.

This is hard to address because of how the language was designed, as the error is not properly caused inside the function, and we don’t have traits as a first class language feature. I don’t see how this could be done.

I do like more the way you phrase the error, it looks clearer than the current one. :slight_smile:

Given my roommates are either computer scientist or from humanistic areas, I would get wildly different responses. :stuck_out_tongue_winking_eye:

Jokes aside, your criticism is very constructive, just that I don’t think your last point is easily solvable. At least not yet.

6 Likes
  1. Fails to identify which line the error occurs on

Works for me:

The first line shows the error to be on line 5, which is indeed correct. You have to toggle line numbers in cells though, default is (as in regular Jupyter notebooks) that they’re switched off:

image

9 Likes

Doesn’t specify range though. Which is a source of confusion.

3 Likes

expected Union{Nothing, Integer}, got a value of type Float64

It looks possible to modify Julia in order to change the error message like

expected either Integer or nothing (Union{Nothing, Integer}), got a value of type Float64

Would it be easier to read ?

7 Likes
julia> x = range(0,10,length=nothing)
0:10

A length of type Nothing is allowed, so the current error message is correct, while the suggested rewrite is not. One may discuss whether the range function should allow length=nothing, but given its current implementation the error message is fine.

1 Like

To be fair, while it doesn’t lie, it is hard to interpret for a beginner.

ERROR: TypeError: in keyword argument length, expected Union{Nothing, Integer}, got a value of type Float64

This makes it sound like the argument should be of type Union{Nothing, Integer}. Except, how does one create that type?

julia> Union{Nothing, Integer}(3)
ERROR: MethodError: no method matching Union{Nothing, Integer}(::Int64)

That doesn’t work, and it also doesn’t tell me what I should do. One can search for help on Union, but that’s probably a waste of their time for something so trivial.

Unless I know that Union{Nothing, Integer} means “either an Integer, or nothing”, it’s not obvious to a beginner. I would say that the error message might be improved here to make it easier to understand. A beginner shouldn’t be required to understand Union types to get their work done, that’s an unnecessarily steep learning curve when there’s a simpler solution.

Also, if someone specifies a numerical value for length, it’s probably reasonable to assume that they don’t intend that argument to be nothing. The fact that it may accept nothing is likely irrelevant in this context.

5 Likes

Are you suggesting hardcoding it for the range function, or changing how Union is printed generally? Because to me reading about how Union types work isn’t that high a requirement. It’s easily googleable (Julia Union gets you right there), and once you know what it means it’s a more compact description than natural language versions, especially for larger union types.

And we don’t “simplify” other abstract types.

5 Likes

I’m suggesting changing how a TypeError is shown if the expected type is a Union. Instead of Union{Nothing, Integer} it may say “an Integer or nothing”, which conveys the same information.

I understand that Union{Nothing, Integer} is a more compact description that’s googleable, however, in this case, the bar to a user-friendly error message doesn’t appear to be high.

4 Likes

That doesn’t seem to be too unreasonable, going from

expected Union{Nothing, Integer}, got a value of type Float64

to

expected value to be of type Integer or Nothing, got a value of type Float64
10 Likes

I think that @gustaphe’s concern is about scalability when the Union gets more complex (e.g. nested).
Integration with a clickable Union link to a doc pane (à la RStudio) in vscode could be a good trade-off between current compact error message (which drives you toward a better understanding of Julia’s type sytem) and user-friendlyness.

3 Likes

I’d say, as a beginner, it is worth spending time learning the error message. Or in other words, beginners should learn how to read the basic error message. Here, Union is a thing to learn, whether you like it or not, you will encounter it sometime.

8 Likes

How about changing the help text so it says type of X when X is a concrete type and subtype of Y when Y is an abstract type? I would say that trying to find an object that is an instance of a Union{Integer, Nothing} is indeed confusing because it can’t be done in that sense.

5 Likes

Perhaps an error hint may be added to clarify this, instead of changing the error message if this is deemed to be difficult.

I agree so much with this. It was one of the first thing I tried to learn and it was immensely helpful (and it is always one of the first things I teach in classes).

I think the error message really just lacks the information that the keyword argument length directly refers to the range() function.

I honestly think something like (as suggested by @nilshg)

expected value to be of type Integer or Nothing, got a value of type Float64

is just more confusing, because this could also mean that 2 functions exist, one of which expects an Integer, one of which expects type Nothing (obviously nonsense with Integer, but not in other Union cases).

My hope would be that explicitly referring to the function is helpful to beginners e.g.

ERROR: TypeError: in keyword argument length of function range(), expected Union{Nothing, Integer}, got a value of type Float64
2 Likes

Definitely agree the wording could be improved. Would you be willing to open a GitHub issue about the wording of this message?

9 Likes

Absolutely. This’d be my first GitHub issue–can ya point me to where exactly I should do it?

1 Like

Oh! I had no idea that tiny number 5 buried in the stacktrace is a line number! Would be good to label it “Line 5” and print it first.

Thanks for the tip on showing line numbers in notebook cells!

5 Likes