roc icon indicating copy to clipboard operation
roc copied to clipboard

Improve error messages for method calls lacking empty parentheses

Open fpsvogel opened this issue 1 month ago • 5 comments

~~When I try to use List.len with static dispatch, it raises a TypeMismatch error. If explicitly use List.len, it works as expected.~~

EDIT: An error is to be expected, due to a missing empty parentheses in my_list.len in the example below. But two improvements are possible:

  • The error message could be improved so that it's clear that a method call is missing parentheses.
  • Method calls could more consistently require parentheses. Sometimes no error is raised when parentheses are omitted (example in a reply below).

Example (in a file in test/fx):

app [main!] { pf: platform "./platform/main.roc" }

main! = || {
  my_list = [1, 2, 3]
  dbg List.len(my_list) # ok
  dbg my_list.len # raises TypeMismatch error
}

Error output:

-- TYPE MISMATCH ---------------------------------

This expression is used in an unexpected way:
  ┌─ test/fx/_test.roc:8:7
  │
8 │   dbg list.len
  │       ^^^^

It has the type:
    List(a) where [a.from_numeral : Numeral -> Try(_b, [InvalidNumeral(Str)])]

But I expected it to be:
    { len: _field }

Found 1 error(s) and 0 warning(s) for test/fx/_test.roc.
ROC DBG: 3

Roc crashed: Error evaluating from shared memory: TypeMismatch

fpsvogel avatar Nov 30 '25 14:11 fpsvogel

I found that adding empty parentheses after len prevents the error:

# in test/fx
app [main!] { pf: platform "./platform/main.roc" }

main! = || {
  list = [1, 2, 3]
  dbg List.len(list)
  dbg list.len()
}

Are parentheses meant to be required for zero-arg method calls? If so, we can close this issue.

fpsvogel avatar Nov 30 '25 20:11 fpsvogel

Yeah, I spent a long time on this before I realized that I think this is intended behavior; it should be my_list.len() and my_list.len should produce an error (@rtfeldman ?). We can leave this issue open, because the error message should be improved.

Anton-4 avatar Nov 30 '25 20:11 Anton-4

Gotcha, sorry for the false alarm.

The reason I didn't catch that initially, is that I've omitted the parentheses before, and not run into an error. This example doesn't produce an error, even though the last line omits the parens:

# in test/fx
app [main!] { pf: platform "./platform/main.roc" }

import pf.Stdout

main! = || {
  "1\n2\n3"
    .split_on("\n")
    ->Str.join_with(" ")
    ->Stdout.line!
}

Should this example raise an error also?

fpsvogel avatar Nov 30 '25 20:11 fpsvogel

It's correct that my_list.len should produce an error - ideally one that suggests .len()!

rtfeldman avatar Nov 30 '25 22:11 rtfeldman

Thanks for confirming @rtfeldman!

@Anton-4 I've edited the title and description of this issue to reflect that errors are expected in these cases, and what could be improved about them.

Feel free to de-prioritize this issue if there are more pressing things to work on. The impact may be limited; it will probably only trip up Ruby programmers like me!

fpsvogel avatar Dec 01 '25 02:12 fpsvogel