-
Notifications
You must be signed in to change notification settings - Fork 833
Description
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 10In 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
Labels
Type
Projects
Status