The spec imported from Scala 2 still says:
If an implicit argument is not found by implicit search, it may be supplied using a default argument.
I see there was a ticket requesting clarification, and I see that I was going to add it in the section on “function applications” but was persuaded that it belonged in the section on “method definitions”, which is why I had trouble finding it just now.
Neither “applications” in chapter 6 nor “implicit parameters” in chapter 7 mention this interaction. This is odd because “named and default args” go together, but really, first you sort out “what the user wrote” as named and positional args, then you supply implicits, then you add defaults. (For overloading, this must determine “applicability”.)
This does not work:
scala> def f(i: Int)(using String = "hi") = summon[String] * i
-- [E040] Syntax Error: ------------------------------------------------------------------------------------------------
1 |def f(i: Int)(using String = "hi") = summon[String] * i
| ^
| ')' expected, but '=' found
scala> def f(i: Int)(using s: String = "hi") = summon[String] * i
def f(i: Int)(using s: String): String
I’m embarrassed that I used the same example from the spec, before I had looked it up. Am I in an example rut?
Chapter 7 says
A method with implicit parameters can be applied to arguments just like a normal method. In this case the implicit
label has no effect. However, if such a method misses arguments for its implicit parameters, such arguments will be automatically provided.
But this works (and works the same in Scala 2):
scala> def f(i: Int)(using s: String = "hi", j: Int = 10) = summon[String] * (i*j)
def f(i: Int)(using s: String, j: Int): String
scala> f(2)(using j = 3)
val res3: String = hihihihihihi
I guess “has no effect” means “no further action is taken when an arg is supplied explicitly”, not that the parameter list is suddenly taken as “not implicit”. Some other comments on the PR also confused me on this score. In a word, I would expect chapter 6, after all, to explain how my expression f(2)(using j = 3)
is interpreted.
Note that erroring for named applications was recently tweaked, so it’s important to ask these questions about how stuff works without assuming it must work as expected (for a given expectation of what is expected). Also, we must not assume that only “new” features need specification. (I still have to go back and see if a behavior with varargs changed, or if I never understood how it works, note to self.)