codeworld icon indicating copy to clipboard operation
codeworld copied to clipboard

Use of % in standard math way leads to poor error message

Open codeworld-feedback opened this issue 3 years ago • 4 comments

Program: https://code.world/#Ps3E8U_mDfncXB1orlHmC_w

Message:

program.hs:5:1: error:
    parse error
    • If this line continues the previous definition, indent it.
    • Otherwise, are you missing a parenthesis on the previous line)?

codeworld-feedback avatar Sep 23 '20 19:09 codeworld-feedback

Unfortunately, we don't have a great way to catch this error because it fails to parse.

cdsmith avatar Sep 24 '20 01:09 cdsmith

Hi, Chris,

I don't know how you preprocess the code.world "simplified" language, but I guess you do to transpile the language using parentheses for functions calls to standard Haskell.

I could imagine adding a special parsing rule that a "sticky" postfix % after a number is translated -- something like s/(\d+)%/$1 \/ 100/ -- could work.

Of course this would limit the use of the "proper" Data.Ratio.% to be only usable with spaces around it, so only 1 % 8 would be valid, but 1%8 or 1% 8 not, but maybe that constructor wouldn't be used that much anyway by the target audience.

s/(\d)%[^\d]/$1 / 100$2/ would actually only disallow 1% 8 (and that's likely unintended/an error), but still leave 1%8 valid.

Just brainstorming, I have no stake in this issue.

szabi avatar Sep 17 '21 18:09 szabi

Code is parsed with the GHC API. Unfortunately, in this case, the code doesn't parse at all, so it's tough to look for anything. I could see adding some kind of ad hoc rule here where, for instance, if the regular expression \b[0-9]*([.][0-9]*)?% matches anywhere in the source file, and the location is near the parse error, then we could do something. But this is vague enough that I'd definitely want to just give an error message rather than trying to correct it and succeed at running the program.

To make it even harder, the parse error isn't reported until the next line. So we need something like at least a lexical scanner to decide when a parse error is on the next token after a regular expression match. In this case, it's three whole lines away! Se #1354 for more about this. A lexical scanner like this would be useful for many parse errors.

Putting this together, ideally, I'd like to see this program fail with something like:

Line 2, Column 11: error:
    Percent notation is not allowed.  Write 0.6 instead of 60%.

cdsmith avatar Sep 17 '21 18:09 cdsmith

This comment is assuming the suggested target error message is dynamic, referencing the actual input string, rather than static with a fixed example of "0.6" vs "60%":

Again, we are in the range of marginal improvements, but as we are aiming at coding-naive -- and possibly relatively math-naive -- audiences once discussing this feature, a minor improvement to that "target" error message might be

Percent notation is not allowed. Write 0.60 instead of 60%., writing 0.60 instead of 0.6; this would give those, who are not well versed with the decimal vs. % notation to still have a better chance to figure out the relationship.

(I don't think that's too much of hand-holding. On the one hand, we'd expect some mathematical literacy, on the other hand, an educational platform should be low barriers. And we have witnessed in the example attached to this very issue that someone actually wanted to write something that essentially amounts to "62.345$ - 60%", which seems to indicate low mathematical literacy as well, so that's definitely within the range of the target user base.)

As a rule of thumb, I'd say the displayed number should always include the second post-decimal place (even if zero), and possibly more (if a fractional percentage point was used), so certainly:

  • Percent notation is not allowed. Write 0.05 instead of 5%.
  • Percent notation is not allowed. Write 0.60 instead of 60%.
  • Percent notation is not allowed. Write 0.055 instead of 5.5%.
  • Percent notation is not allowed. Write 0.6025 instead of 60.25%.

szabi avatar Sep 20 '21 11:09 szabi