We cannot mix implicit and non-implicit formal parameters within a single parameter list because implicit
modifier is a property of the list, not the parameter. Hence the following method definition is illegal
def foo(msg: String, implicit n: Int) = ??? // Error
however why then is the following legal
class Foo(val msg: String, implicit val n: Int) // OK
Here it appears it is legal to mix implicit and non-implicit parameters within a single parameter clause when declaring a class constructor, however the implicit
modifier does not apply to the formal parameter n
but instead it is modifying corresponding automatically generated accessor member. Because we have declared n
to be val
this expands to something like
class Foo {
...
implicit def n(): Int = n;
def <init>(msg: String, n: Int) = { // note how msg and n are *NOT* implicit
...
}
}
and it is perfectly legal to declare a member to be implicit. On the other hand, if we drop val
declaration, thus not declaring a member, we see it does not compile
class Foo(val msg: String, implicit n: Int) // Error: 'val' expected but identifier found ^
similarly to how it is illegal within a method definition. Therefore the reason why the following does not compile
implicit val num: Int = 4
new Foo("yo") // error: unspecified value parameter n
is because the formal parameter n
is in fact not implicit.
As a side note, the following Scala 2 requirement
A method or constructor can have only one implicit parameter list, and
it must be the last parameter list given.
has been altered by Scala 3 Multiple Given Clauses
There can be several given parameter clauses in a definition and
given parameter clauses can be freely mixed with normal ones.
Example:
def f(u: Universe)(given ctx: u.Context)(given s: ctx.Symbol, k: ctx.Kind) = ...
where given
corresponds to implicit
.
implicit
in this case isn't solving anything or doing anything. – Wrongdoer