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:parser
to 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 thate
be applicable to theargs
. In particular, the args are typechecked according to the parameter types ofe
.e(args)
is taken ase.apply(args)
ife
is a value, butscaled
is a method.You're hoping for "implicit application" to insert the implicit args, but that only applies when
e
is 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)
, thee
is not an application likee(arg)
, so you benefit from conversions like implicit application.