There is a note in Cay Horstmann's book "Scala for the Impatient" about the apply method:
Occasionally, the () notation conflicts with another Scala feature: implicit parameters. For example, the expression
"Bonjour".sorted(3)yields an error because the sorted method can optionally be called with an ordering, but 3 is not a valid ordering.
The solution is to assign "Bonjour".sorted to a variable and call apply on it, for example:
val result = "Bonjour".sorted
result(3)
Or call apply explicitly:
"Bonjour".sorted.apply(3)
But why this doesn't work and produces a compile error:
("Bonjour".sorted)(3)
The sorted method returns a String, which can be imlicitly converted to a StringOps and parentheses are used to wrap the string expression.
Why compiler doesn't accept to call the apply method of a StringOps?
You can use
-Xprint:parserto see that the parens are discarded early:The extra parens do nothing. The compiler just sees an application
expr(args). Because it's an application, you don't get "implicit application" conversion.In any case, the meaning of
scaled, a method, depends on the expected type.The reason we expect the extra parens to make a difference is that parens override precedence of operators. But
(x)is justx.Possibly the spec is actually clear about this:
e(args)requires thatebe applicable to theargs. In particular, the args are typechecked according to the parameter types ofe.e(args)is taken ase.apply(args)ifeis a value, butscaledis a method.You're hoping for "implicit application" to insert the implicit args, but that only applies when
eis not already applied. Or that(e)(args)could be taken as(e(_))(args), that is,(x => e(x))(arg).When written as
e.apply(arg), theeis not an application likee(arg), so you benefit from conversions like implicit application.