Skip to content

Improve error reporting: Need parentheses on arguments #5475

@isaacabraham

Description

@isaacabraham

What

The following code snippet gives an error which is very confusing for beginners.

let add a b = a + b
let multiply (a:int) (b:int) = a * b

multiply 5 add 5 10
^^^^^^^^^^^^^^

error FS0003: This value is not a function and cannot be applied.

(as an aside I had to explicitly type annotate multiply otherwise the compiler infers a completely different signature for it!)

Why

The issue (from what I understand) is that F# can't correctly resolve the precedence of the function calls i.e. It picks (multiply 5 add) 5 10 instead of multiply 5 (add 5 10). The solution is indeed to explicitly wrap the add expression in parentheses, whereby the compiler happily figures everything out.

How

In a perfect world

Invalid function arguments. The compiler cannot understand the order of function calls and arguments from this callsite. Did you mean to pass the result of "add 5 10" as an argument into "multiply"? If so, wrap the "inlined" function call in parentheses e.g. multiply 5 (add 5 10)".

Next option

I suspect that this would be difficult to do - if so, how about a more generic error message like:

Invalid function arguments. The compiler cannot understand the order of function calls and arguments from this callsite. Are you passing the result of one function call directly into another function call? If so, consider wrapping the inline function call in parentheses e.g. "foo a bar b" should be rewritten as "foo a (bar b)".

Last option

Another approach is to consider that the compiler seems to be assuming this precedence:

(multiply 5 add) 5 10

In such a case, why doesn't the compiler give an error such as:

multiply 5 add 5 10
           ^^^
This expression was expected to have type
    'int'
but here has type
    'int -> int -> int'

Whilst not perfect, I think that this would be a little better than the current error message.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    New

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions