Why should successive arguments involving method application be parenthesized?

f#

Solution

I think that the problem here is that the code could be treated as:

let z3 = f 1 rng.Next (5)

This would be equivalent to omitting the parentheses and so it would be calling `f` with 3 arguments (the second being a function value). This sounds a bit silly, but the compiler actually does not strictly insist on having a space between parameters. For example:

let second a b = b
add 5(1)          // This works fine and calls 'add 5 1'
add id(1)         // error FS0597
add rng.Next(5)   // error FS0597
add (rng.Next(5)) // This works fine (partial application)

I think the problem is that if you look at the sequence of the 4 examples in the above snippet, it is not clear which behavior should you get in the second and the third case.

The call `rng.Next(5)` is still treated in a special way, because F# allows you to chain calls if they are formed by single-parameter application without space. For example `rng.Next(5).ToString()`. But, for example, writing `second(1)(2)` is allowed, but `second(1)(2).ToString()` will not work.

Problem

Suppose the following F# function: ``` let f (x:int) (y:int) = 42 ``` I suspect that the reason I need to parenthesize the arguments in example z2 below is because of type inference; my example might not be great, but it's easy to imagine how things could get very hairy: ``` let z1 = f 2 3 let z2 = f 2 (f 3 5) ``` However, the following case is less clear to me: ``` let rng = System.Random() let z3 = f 1 rng.Next(5) ``` z3 doesn't work, with a clear error message: error FS0597: Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized. Fixing it is trivial (parenthesize all the things), but what I am not clear about is why such an expression is a problem. I assume this has to do with type inference again, but naively, it seems to me that here, methods having a list of arguments surrounded by a parenthesis would actually make things less potentially ambiguous. Does this have to do with the fact that `rng.Next(5)` is equivalent to `rng.Next 5`? Can someone hint, give an example or explain why this rule is needed, or what type of problems would arise if it were not there?

Original source