I've come across some Scala behavior that I can't quite explain.
Let's say we have an overloaded method.
def foo = List('a','b','c') //NoArgFoo
def foo(x: Int*) = List('X','Y','Z') //VarArgsFoo
[Note: Order doesn't matter but they have to be in the same compilation unit. As two separate lines in the REPL one will simply shadow the other.]
Now let's try some various ways to invoke the method/s.
foo //res0: List[Char] = List(a, b, c) <--NoArgFoo
foo() //res1: List[Char] = List(X, Y, Z) <--VarArgsFoo
foo(1) //res2: Char = b <--NoArgFoo.apply(1)
foo(1, 2) //res3: List[Char] = List(X, Y, Z) <--VarArgsFoo
Now let's change the foo type to String, which also has an apply() method.
foo //res0: String = ABC <--NoArgFoo
foo() //res1: String = xyz <--VarArgsFoo
foo(1) //res2: String = xyz <--VarArgsFoo
foo(1, 2) //res3: String = xyz <--VarArgsFoo
This seemed odd until I recalled that apply() is not native to java.lang.String. It's made available via an implicit conversion, and since the compiler won't invoke an implicit if it doesn't have to then this result makes sense. But now we have inconsistent behavior.
So, is the precedence of apply() over varargs a bug or a feature? Is it just the result of some arbitrary/capricious choice made by the compiler's authors? Is it an unavoidable consequence of the varargs mechanism?